<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Tutorial</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../parser.html" title="Chapter 25. Boost.Parser">
<link rel="prev" href="cheat_sheet.html" title="Cheat Sheet">
<link rel="next" href="extended_examples.html" title="Extended Examples">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cheat_sheet.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../parser.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="extended_examples.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_parser.tutorial"></a><a class="link" href="tutorial.html" title="Tutorial">Tutorial</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.terminology">Terminology</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.hello__whomever">Hello, Whomever</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.a_trivial_example">A Trivial Example</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.a_trivial_example_that_gracefully_handles_whitespace">A
      Trivial Example That Gracefully Handles Whitespace</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.semantic_actions">Semantic Actions</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.parsing_to_find_subranges">Parsing
      to Find Subranges</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.the_parse_context">The Parse Context</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.rule_parsers">Rule Parsers</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.parsing_into__struct_s_and__class_es">Parsing
      into <code class="computeroutput"><span class="keyword">struct</span></code>s and <code class="computeroutput"><span class="keyword">class</span></code>es</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.alternative_parsers">Alternative
      Parsers</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.parsing_quoted_strings">Parsing
      Quoted Strings</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.parsing_in_detail">Parsing In Detail</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.backtracking">Backtracking</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.symbol_tables">Symbol Tables</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.mutable_symbol_tables">Mutable
      Symbol Tables</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.the_parsers_and_their_uses">The
      Parsers And Their Uses</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.directives">Directives</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.combining_operations">Combining
      Operations</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.attribute_generation">Attribute
      Generation</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.the__parse____api">The <code class="computeroutput"><span class="identifier">parse</span><span class="special">()</span></code> API</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.more_about_rules">More About Rules</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.algorithms_and_views_that_use_parsers">Algorithms
      and Views That Use Parsers</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.unicode_support">Unicode Support</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.callback_parsing">Callback Parsing</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.error_handling_and_debugging">Error
      Handling and Debugging</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.memory_allocation">Memory Allocation</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.best_practices">Best Practices</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_parser.tutorial.writing_your_own_parsers">Writing
      Your Own Parsers</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.terminology"></a><a class="link" href="tutorial.html#boost_parser.tutorial.terminology" title="Terminology">Terminology</a>
</h3></div></div></div>
<p>
        First, let's cover some terminology that we'll be using throughout the docs:
      </p>
<p>
        A <span class="emphasis"><em>semantic action</em></span> is an arbitrary bit of logic associated
        with a parser, that is only executed when the parser matches.
      </p>
<p>
        Simpler parsers can be combined to form more complex parsers. Given some
        combining operation <code class="computeroutput"><span class="identifier">C</span></code>, and
        parsers <code class="computeroutput"><span class="identifier">P0</span></code>, <code class="computeroutput"><span class="identifier">P1</span></code>, ... <code class="computeroutput"><span class="identifier">PN</span></code>,
        <code class="computeroutput"><span class="identifier">C</span><span class="special">(</span><span class="identifier">P0</span><span class="special">,</span> <span class="identifier">P1</span><span class="special">,</span> <span class="special">...</span> <span class="identifier">PN</span><span class="special">)</span></code> creates a new parser <code class="computeroutput"><span class="identifier">Q</span></code>.
        This creates a <span class="emphasis"><em>parse tree</em></span>. <code class="computeroutput"><span class="identifier">Q</span></code>
        is the parent of <code class="computeroutput"><span class="identifier">P1</span></code>, <code class="computeroutput"><span class="identifier">P2</span></code> is the child of <code class="computeroutput"><span class="identifier">Q</span></code>,
        etc. The parsers are applied in the top-down fashion implied by this topology.
        When you use <code class="computeroutput"><span class="identifier">Q</span></code> to parse a
        string, it will use <code class="computeroutput"><span class="identifier">P0</span></code>,
        <code class="computeroutput"><span class="identifier">P1</span></code>, etc. to do the actual
        work. If <code class="computeroutput"><span class="identifier">P3</span></code> is being used
        to parse the input, that means that <code class="computeroutput"><span class="identifier">Q</span></code>
        is as well, since the way <code class="computeroutput"><span class="identifier">Q</span></code>
        parses is by dispatching to its children to do some or all of the work. At
        any point in the parse, there will be exactly one parser without children
        that is being used to parse the input; all other parsers being used are its
        ancestors in the parse tree.
      </p>
<p>
        A <span class="emphasis"><em>subparser</em></span> is a parser that is the child of another
        parser.
      </p>
<p>
        The <span class="emphasis"><em>top-level parser</em></span> is the root of the tree of parsers.
      </p>
<p>
        The <span class="emphasis"><em>current parser</em></span> or <span class="emphasis"><em>bottommost parser</em></span>
        is the parser with no children that is currently being used to parse the
        input.
      </p>
<p>
        A <span class="emphasis"><em>rule</em></span> is a kind of parser that makes building large,
        complex parsers easier. A <span class="emphasis"><em>subrule</em></span> is a rule that is
        the child of some other rule. The <span class="emphasis"><em>current rule</em></span> or <span class="emphasis"><em>bottommost
        rule</em></span> is the one rule currently being used to parse the input that
        has no subrules. Note that while there is always exactly one current parser,
        there may or may not be a current rule — rules are one kind of parser,
        and you may or may not be using one at a given point in the parse.
      </p>
<p>
        The <span class="emphasis"><em>top-level parse</em></span> is the parse operation being performed
        by the top-level parser. This term is necessary because, though most parse
        failures are local to a particular parser, some parse failures cause the
        call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> to indicate failure of the
        entire parse. For these cases, we say that such a local failure "causes
        the top-level parse to fail".
      </p>
<p>
        Throughout the Boost.Parser documentation, I will refer to "the call
        to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>". Read this as "the
        call to any one of the functions described in <a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api" title="The parse() API">The
        <code class="computeroutput"><span class="identifier">parse</span><span class="special">()</span></code>
        API</a>". That includes <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa3a1f9c9842a7d78f838d924ec01f46a.html" title="Function template prefix_parse">prefix_parse()</a></code>,
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab9e8e193ef875ca869f2d6d43fa61fc5.html" title="Function template callback_parse">callback_parse()</a></code>, and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a238bfc6fa7bebba8f6431fa163aae0d6.html" title="Function template callback_prefix_parse">callback_prefix_parse()</a></code>.
      </p>
<p>
        There are some special kinds of parsers that come up often in this documentation.
      </p>
<p>
        One is a <span class="emphasis"><em>sequence parser</em></span>; you will see it created using
        <code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;&gt;</span></code>,
        as in <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;&gt;</span>
        <span class="identifier">p2</span> <span class="special">&gt;&gt;</span>
        <span class="identifier">p3</span></code>. A sequence parser tries to
        match all of its subparsers to the input, one at a time, in order. It matches
        the input iff all its subparsers do.
      </p>
<p>
        Another is an <span class="emphasis"><em>alternative parser</em></span>; you will see it created
        using <code class="computeroutput"><span class="keyword">operator</span><span class="special">|</span></code>,
        as in <code class="computeroutput"><span class="identifier">p1</span> <span class="special">|</span>
        <span class="identifier">p2</span> <span class="special">|</span>
        <span class="identifier">p3</span></code>. An alternative parser tries
        to match all of its subparsers to the input, one at a time, in order; it
        stops after matching at most one subparser. It matches the input iff one
        of its subparsers does.
      </p>
<p>
        Finally, there is a <span class="emphasis"><em>permutation parser</em></span>; it is created
        using <code class="computeroutput"><span class="keyword">operator</span><span class="special">||</span></code>,
        as in <code class="computeroutput"><span class="identifier">p1</span> <span class="special">||</span>
        <span class="identifier">p2</span> <span class="special">||</span>
        <span class="identifier">p3</span></code>. A permutation parser tries
        to match all of its subparsers to the input, in any order. So the parser
        <code class="computeroutput"><span class="identifier">p1</span> <span class="special">||</span>
        <span class="identifier">p2</span> <span class="special">||</span>
        <span class="identifier">p3</span></code> is equivalent to <code class="computeroutput"><span class="special">(</span><span class="identifier">p1</span> <span class="special">&gt;&gt;</span>
        <span class="identifier">p2</span> <span class="special">&gt;&gt;</span>
        <span class="identifier">p3</span><span class="special">)</span> <span class="special">|</span> <span class="special">(</span><span class="identifier">p1</span>
        <span class="special">&gt;&gt;</span> <span class="identifier">p3</span>
        <span class="special">&gt;&gt;</span> <span class="identifier">p2</span><span class="special">)</span> <span class="special">|</span> <span class="special">(</span><span class="identifier">p2</span> <span class="special">&gt;&gt;</span> <span class="identifier">p1</span> <span class="special">&gt;&gt;</span> <span class="identifier">p3</span><span class="special">)</span> <span class="special">|</span>
        <span class="special">(</span><span class="identifier">p2</span> <span class="special">&gt;&gt;</span> <span class="identifier">p3</span> <span class="special">&gt;&gt;</span> <span class="identifier">p1</span><span class="special">)</span> <span class="special">|</span> <span class="special">(</span><span class="identifier">p3</span> <span class="special">&gt;&gt;</span> <span class="identifier">p1</span> <span class="special">&gt;&gt;</span> <span class="identifier">p2</span><span class="special">)</span> <span class="special">|</span>
        <span class="special">(</span><span class="identifier">p3</span> <span class="special">&gt;&gt;</span> <span class="identifier">p2</span> <span class="special">&gt;&gt;</span> <span class="identifier">p1</span><span class="special">)</span></code>. Hopefully the advantage of its terseness
        is self-explanatory. It matches the input iff all of its subparsers do, regardless
        of the order they match in.
      </p>
<p>
        Boost.Parser parsers each have an <span class="emphasis"><em>attribute</em></span> associated
        with them, or explicitly have no attribute. An attribute is a value that
        the parser generates when it matches the input. For instance, the parser
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6e37283853b49605ec05b4a1969eaaac.html" title="Global double_">double_</a></code>
        generates a <code class="computeroutput"><span class="keyword">double</span></code> when it matches
        the input. <span class="emphasis"><em><code class="literal">ATTR</code></em></span><code class="computeroutput"><span class="special">()</span></code>
        is a notional macro that expands to the attribute type of the parser passed
        to it; <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6e37283853b49605ec05b4a1969eaaac.html" title="Global double_">double_</a><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">double</span></code>.
        This is similar to the <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1attribute.html" title="Struct template attribute">attribute</a></code> type trait.
      </p>
<p>
        Next, we'll look at some simple programs that parse using Boost.Parser. We'll
        start small and build up from there.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.hello__whomever"></a><a class="link" href="tutorial.html#boost_parser.tutorial.hello__whomever" title="Hello, Whomever">Hello, Whomever</a>
</h3></div></div></div>
<p>
        This is just about the most minimal example of using Boost.Parser that one
        could write. We take a string from the command line, or <code class="computeroutput"><span class="string">"World"</span></code>
        if none is given, and then we parse it:
      </p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">parser</span><span class="special">/</span><span class="identifier">parser</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>


<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">argc</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span> <span class="special">*</span> <span class="identifier">argv</span><span class="special">[])</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">input</span> <span class="special">=</span> <span class="string">"World"</span><span class="special">;</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="number">1</span> <span class="special">&lt;</span> <span class="identifier">argc</span><span class="special">)</span>
        <span class="identifier">input</span> <span class="special">=</span> <span class="identifier">argv</span><span class="special">[</span><span class="number">1</span><span class="special">];</span>

    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">result</span><span class="special">;</span>
    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">,</span> <span class="identifier">result</span><span class="special">);</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Hello, "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span> <span class="special">&lt;&lt;</span> <span class="string">"!\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        The expression <code class="computeroutput"><span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span></code>
        is a parser-expression. It uses one of the many parsers that Boost.Parser
        provides: <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>.
        Like all Boost.Parser parsers, it has certain operations defined on it. In
        this case, <code class="computeroutput"><span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span></code>
        is using an overloaded <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code> as the C++ version of a <a href="https://en.wikipedia.org/wiki/Kleene_star" target="_top">Kleene
        star</a> operator. Since C++ has no postfix unary <code class="computeroutput"><span class="special">*</span></code>
        operator, we have to use the one we have, so it is used as a prefix.
      </p>
<p>
        So, <code class="computeroutput"><span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span></code>
        means "any number of characters". In other words, it really cannot
        fail. Even an empty string will match it.
      </p>
<p>
        The parse operation is performed by calling the <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        function, passing the parser as one of the arguments:
      </p>
<pre class="programlisting"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">,</span> <span class="identifier">result</span><span class="special">);</span>
</pre>
<p>
        The arguments here are: <code class="computeroutput"><span class="identifier">input</span></code>,
        the range to parse; <code class="computeroutput"><span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span></code>,
        the parser used to do the parse; and <code class="computeroutput"><span class="identifier">result</span></code>,
        an out-parameter into which to put the result of the parse. Don't get too
        caught up on this method of getting the parse result out of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>; there are multiple ways
        of doing so, and we'll cover all of them in subsequent sections.
      </p>
<p>
        Also, just ignore for now the fact that Boost.Parser somehow figured out
        that the result type of the <code class="computeroutput"><span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span></code>
        parser is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>. There are clear rules for this
        that we'll cover later.
      </p>
<p>
        The effects of this call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        is not very interesting — since the parser we gave it cannot ever
        fail, and because we're placing the output in the same type as the input,
        it just copies the contents of <code class="computeroutput"><span class="identifier">input</span></code>
        to <code class="computeroutput"><span class="identifier">result</span></code>.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.a_trivial_example"></a><a class="link" href="tutorial.html#boost_parser.tutorial.a_trivial_example" title="A Trivial Example">A Trivial Example</a>
</h3></div></div></div>
<p>
        Let's look at a slightly more complicated example, even if it is still trivial.
        Instead of taking any old <code class="computeroutput"><span class="keyword">char</span></code>s
        we're given, let's require some structure. Let's parse one or more <code class="computeroutput"><span class="keyword">double</span></code>s, separated by commas.
      </p>
<p>
        The Boost.Parser parser for <code class="computeroutput"><span class="keyword">double</span></code>
        is <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6e37283853b49605ec05b4a1969eaaac.html" title="Global double_">double_</a></code>.
        So, to parse a single <code class="computeroutput"><span class="keyword">double</span></code>,
        we'd just use that. If we wanted to parse two <code class="computeroutput"><span class="keyword">double</span></code>s
        in a row, we'd use:
      </p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">double_</span> <span class="special">&gt;&gt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">double_</span>
</pre>
<p>
        <code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;&gt;</span></code>
        in this expression is the sequence-operator; read it as "followed by".
        If we combine the sequence-operator with <a href="https://en.wikipedia.org/wiki/Kleene_star" target="_top">Kleene
        star</a>, we can get the parser we want by writing:
      </p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">double_</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="char">','</span> <span class="special">&gt;&gt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">double_</span><span class="special">)</span>
</pre>
<p>
        This is a parser that matches at least one <code class="computeroutput"><span class="keyword">double</span></code>
        — because of the first <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6e37283853b49605ec05b4a1969eaaac.html" title="Global double_">double_</a></code> in the expression
        above — followed by zero or more instances of a-comma-followed-by-a-<code class="computeroutput"><span class="keyword">double</span></code>. Notice that we can use <code class="computeroutput"><span class="char">','</span></code> directly. Though it is not a parser, <code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;&gt;</span></code>
        and the other operators defined on Boost.Parser parsers have overloads that
        accept character/parser pairs of arguments; these operator overloads will
        create the right parser to recognize <code class="computeroutput"><span class="char">','</span></code>.
      </p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">parser</span><span class="special">/</span><span class="identifier">parser</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>


<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Enter a list of doubles, separated by commas.  No pressure. "</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">input</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">,</span> <span class="identifier">input</span><span class="special">);</span>

    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="char">','</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span><span class="special">));</span>

    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Great! It looks like you entered:\n"</span><span class="special">;</span>
        <span class="keyword">for</span> <span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span> <span class="special">:</span> <span class="special">*</span><span class="identifier">result</span><span class="special">)</span> <span class="special">{</span>
            <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
        <span class="special">}</span>
    <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span>
            <span class="special">&lt;&lt;</span> <span class="string">"Good job!  Please proceed to the recovery annex for cake.\n"</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        The first example filled in an out-parameter to deliver the result of the
        parse. This call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        returns a result instead. As you can see, the result is contextually convertible
        to <code class="computeroutput"><span class="keyword">bool</span></code>, and <code class="computeroutput"><span class="special">*</span><span class="identifier">result</span></code> is some sort of range. In fact,
        the return type of this call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;&gt;</span></code>. Naturally, if the parse fails,
        <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">nullopt</span></code> is returned. We'll look at how
        Boost.Parser maps the type of the parser to the return type, or the filled
        in out-parameter's type, a bit later.
      </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          There's a type trait that can tell you the attribute type for a parser,
          <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1attribute.html" title="Struct template attribute">attribute</a></code>
          (and an associated alias <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1acab73b5438b6bab7862f0409c6845b50.html" title="Type definition attribute_t">attribute_t</a></code>). We'll discuss
          it more in the <a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation" title="Attribute Generation">Attribute
          Generation</a> section.
        </p></td></tr>
</table></div>
<p>
        If I run it in a shell, this is the result:
      </p>
<pre class="programlisting">$ example/trivial
Enter a list of doubles, separated by commas.  No pressure. 5.6,8.9
Great! It looks like you entered:
5.6
8.9
$ example/trivial
Enter a list of doubles, separated by commas.  No pressure. 5.6, 8.9
Good job!  Please proceed to the recovery annex for cake.
</pre>
<p>
        It does not recognize <code class="computeroutput"><span class="string">"5.6, 8.9"</span></code>.
        This is because it expects a comma followed <span class="emphasis"><em>immediately</em></span>
        by a <code class="computeroutput"><span class="keyword">double</span></code>, but I inserted
        a space after the comma. The same failure to parse would occur if I put a
        space before the comma, or before or after the list of <code class="computeroutput"><span class="keyword">double</span></code>s.
      </p>
<p>
        One more thing: there is a much better way to write the parser above. Instead
        of repeating the <code class="computeroutput"><span class="identifier">double_</span></code>
        subparser, we could have written this:
      </p>
<pre class="programlisting"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span> <span class="special">%</span> <span class="char">','</span>
</pre>
<p>
        That's semantically identical to <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="char">','</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span><span class="special">)</span></code>. This pattern — some bit of input
        repeated one or more times, with a separator between each instance —
        comes up so often that there's an operator specifically for that, <code class="computeroutput"><span class="keyword">operator</span><span class="special">%</span></code>.
        We'll be using that operator from now on.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.a_trivial_example_that_gracefully_handles_whitespace"></a><a class="link" href="tutorial.html#boost_parser.tutorial.a_trivial_example_that_gracefully_handles_whitespace" title="A Trivial Example That Gracefully Handles Whitespace">A
      Trivial Example That Gracefully Handles Whitespace</a>
</h3></div></div></div>
<p>
        Let's modify the trivial parser we just saw to ignore any spaces it might
        find among the <code class="computeroutput"><span class="keyword">double</span></code>s and commas.
        To skip whitespace wherever we find it, we can pass a <span class="emphasis"><em>skip parser</em></span>
        to our call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> (we don't need to touch
        the parser passed to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>).
        Here, we use <code class="computeroutput"><span class="identifier">ws</span></code>, which matches
        any Unicode whitespace character.
      </p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">parser</span><span class="special">/</span><span class="identifier">parser</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>


<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Enter a list of doubles, separated by commas.  No pressure. "</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">input</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">,</span> <span class="identifier">input</span><span class="special">);</span>

    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span> <span class="special">%</span> <span class="char">','</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>

    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Great! It looks like you entered:\n"</span><span class="special">;</span>
        <span class="keyword">for</span> <span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span> <span class="special">:</span> <span class="special">*</span><span class="identifier">result</span><span class="special">)</span> <span class="special">{</span>
            <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
        <span class="special">}</span>
    <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span>
            <span class="special">&lt;&lt;</span> <span class="string">"Good job!  Please proceed to the recovery annex for cake.\n"</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        The skip parser, or <span class="emphasis"><em>skipper</em></span>, is run between the subparsers
        within the parser passed to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>.
        In this case, the skipper is run before the first <code class="computeroutput"><span class="keyword">double</span></code>
        is parsed, before any subsequent comma or <code class="computeroutput"><span class="keyword">double</span></code>
        is parsed, and at the end. So, the strings <code class="computeroutput"><span class="string">"3.6,5.9"</span></code>
        and <code class="computeroutput"><span class="string">" 3.6 , \t 5.9 "</span></code>
        are parsed the same by this program.
      </p>
<p>
        Skipping is an important concept in Boost.Parser. You can skip anything,
        not just whitespace; there are lots of other things you might want to skip.
        The skipper you pass to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        can be an arbitrary parser. For example, if you write a parser for a scripting
        language, you can write a skipper to skip whitespace, inline comments, and
        end-of-line comments.
      </p>
<p>
        We'll be using skip parsers almost exclusively in the rest of the documentation.
        The ability to ignore the parts of your input that you don't care about is
        so convenient that parsing without skipping is a rarity in practice.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.semantic_actions"></a><a class="link" href="tutorial.html#boost_parser.tutorial.semantic_actions" title="Semantic Actions">Semantic Actions</a>
</h3></div></div></div>
<p>
        Like all parsing systems (lex &amp; yacc, <a href="https://www.boost.org/doc/libs/release/libs/spirit" target="_top">Boost.Spirit</a>,
        etc.), Boost.Parser has a mechanism for associating semantic actions with
        different parts of the parse. Here is nearly the same program as we saw in
        the previous example, except that it is implemented in terms of a semantic
        action that appends each parsed <code class="computeroutput"><span class="keyword">double</span></code>
        to a result, instead of automatically building and returning the result.
        To do this, we replace the <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6e37283853b49605ec05b4a1969eaaac.html" title="Global double_">double_</a></code> from the previous
        example with <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6e37283853b49605ec05b4a1969eaaac.html" title="Global double_">double_</a><span class="special">[</span><span class="identifier">action</span><span class="special">]</span></code>;
        <code class="computeroutput"><span class="identifier">action</span></code> is our semantic action:
      </p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">parser</span><span class="special">/</span><span class="identifier">parser</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>


<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Enter a list of doubles, separated by commas. "</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">input</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">,</span> <span class="identifier">input</span><span class="special">);</span>

    <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">result</span><span class="special">;</span>
    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">action</span> <span class="special">=</span> <span class="special">[&amp;</span><span class="identifier">result</span><span class="special">](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Got one!\n"</span><span class="special">;</span>
        <span class="identifier">result</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">));</span>
    <span class="special">};</span>
    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">action_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span><span class="special">[</span><span class="identifier">action</span><span class="special">];</span>
    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">success</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">action_parser</span> <span class="special">%</span> <span class="char">','</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>

    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">success</span><span class="special">)</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"You entered:\n"</span><span class="special">;</span>
        <span class="keyword">for</span> <span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">result</span><span class="special">)</span> <span class="special">{</span>
            <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
        <span class="special">}</span>
    <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Parse failure.\n"</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        Run in a shell, it looks like this:
      </p>
<pre class="programlisting">$ example/semantic_actions
Enter a list of doubles, separated by commas. 4,3
Got one!
Got one!
You entered:
4
3
</pre>
<p>
        In Boost.Parser, semantic actions are implemented in terms of invocable objects
        that take a single parameter to a parse-context object. The parse-context
        object represents the current state of the parse. In the example we used
        this lambda as our invocable:
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">action</span> <span class="special">=</span> <span class="special">[&amp;</span><span class="identifier">result</span><span class="special">](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Got one!\n"</span><span class="special">;</span>
    <span class="identifier">result</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">));</span>
<span class="special">};</span>
</pre>
<p>
      </p>
<p>
        We're both printing a message to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span></code>
        and recording a parsed result in the lambda. It could do both, either, or
        neither of these things if you like. The way we get the parsed <code class="computeroutput"><span class="keyword">double</span></code> in the lambda is by asking the parse
        context for it. <code class="computeroutput"><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code> is
        how you ask the parse context for the attribute produced by the parser to
        which the semantic action is attached. There are lots of functions like
        <code class="computeroutput"><span class="identifier">_attr</span><span class="special">()</span></code>
        that can be used to access the state in the parse context. We'll cover more
        of them later on. <a class="link" href="tutorial.html#boost_parser.tutorial.the_parse_context" title="The Parse Context">The
        Parse Context</a> defines what exactly the parse context is and how it
        works.
      </p>
<p>
        Note that you can't write an unadorned lambda directly as a semantic action.
        Otherwise, the compile will see two <code class="computeroutput"><span class="char">'['</span></code>
        characters and think it's about to parse an attribute. Parentheses fix this:
      </p>
<pre class="programlisting"><span class="identifier">p</span><span class="special">[([](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">){/*...*/})]</span>
</pre>
<p>
        Before you do this, note that the lambdas that you write as semantic actions
        are almost always generic (having an <code class="computeroutput"><span class="keyword">auto</span>
        <span class="special">&amp;</span> <span class="identifier">ctx</span></code>
        parameter), and so are very frequently re-usable. Most semantic action lambdas
        you write should be written out-of-line, and given a good name. Even when
        they are not reused, named lambdas keep your parsers smaller and easier to
        read.
      </p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          Attaching a semantic action to a parser removes its attribute. That is,
          <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">[</span><span class="identifier">a</span><span class="special">])</span></code> is always the special no-attribute type
          <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1none.html" title="Struct none">none</a></code>,
          regardless of what type <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
          is.
        </p></td></tr>
</table></div>
<h5>
<a name="boost_parser.tutorial.semantic_actions.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.semantic_actions.semantic_actions_inside_rules"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.semantic_actions.semantic_actions_inside_rules">Semantic
        actions inside rules</a>
      </h5>
<p>
        There are some other forms for semantic actions, when they are used inside
        of <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>.
        See <a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules" title="More About Rules">More About Rules</a>
        for details.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.parsing_to_find_subranges"></a><a class="link" href="tutorial.html#boost_parser.tutorial.parsing_to_find_subranges" title="Parsing to Find Subranges">Parsing
      to Find Subranges</a>
</h3></div></div></div>
<p>
        So far we've seen examples that parse some text and generate associated attributes.
        Sometimes, you want to find some subrange of the input that contains what
        you're looking for, and you don't want to generate attributes at all.
      </p>
<p>
        There are two <span class="emphasis"><em>directive</em></span>s that affect the attribute type
        of any parser, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3960485823df80f6a97f87e811cf7b.html" title="Global raw">raw[]</a></code> and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a8890ba07e65b9e7b1b0f238e94498d.html" title="Global string_view">string_view[]</a></code>.
        (We'll get to directives in more detail in the <a class="link" href="tutorial.html#boost_parser.tutorial.directives" title="Directives">Directives</a>
        section later. For now, you just need to know that a directive wraps a parser,
        and changes some aspect of how it functions.)
      </p>
<h5>
<a name="boost_parser.tutorial.parsing_to_find_subranges.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.parsing_to_find_subranges._globalname_alt__boost__parser__raw___code__phrase_role__identifier__raw__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.parsing_to_find_subranges._globalname_alt__boost__parser__raw___code__phrase_role__identifier__raw__phrase__phrase_role__special______phrase___code___globalname_">raw[]</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3960485823df80f6a97f87e811cf7b.html" title="Global raw">raw[]</a></code> changes the attribute of its
        parser to be a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1subrange.html" title="Struct template subrange">subrange</a></code>
        whose <code class="computeroutput"><span class="identifier">begin</span><span class="special">()</span></code>
        and <code class="computeroutput"><span class="identifier">end</span><span class="special">()</span></code>
        return the bounds of the sequence being parsed that match <code class="computeroutput"><span class="identifier">p</span></code>.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">int_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">%</span> <span class="char">','</span><span class="special">;</span>            <span class="comment">// ATTR(int_parser) is std::vector&lt;int&gt;</span>
<span class="keyword">auto</span> <span class="identifier">subrange_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">raw</span><span class="special">[</span><span class="identifier">int_parser</span><span class="special">];</span>  <span class="comment">// ATTR(subrange_parser) is a subrange</span>

<span class="comment">// Parse using int_parser, generating integers.</span>
<span class="keyword">auto</span> <span class="identifier">ints</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"1, 2, 3, 4"</span><span class="special">,</span> <span class="identifier">int_parser</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">ints</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(*</span><span class="identifier">ints</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;({</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">}));</span>

<span class="comment">// Parse again using int_parser, but this time generating only the</span>
<span class="comment">// subrange matched by int_parser.  (prefix_parse() allows matches that</span>
<span class="comment">// don't consume the entire input.)</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">str</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="string">"1, 2, 3, 4, a, b, c"</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span>
<span class="keyword">auto</span> <span class="identifier">range</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">prefix_parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">subrange_parser</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">range</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">range</span><span class="special">-&gt;</span><span class="identifier">begin</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">range</span><span class="special">-&gt;</span><span class="identifier">end</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()</span> <span class="special">+</span> <span class="number">10</span><span class="special">);</span>

<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same_v</span><span class="special">&lt;</span>
              <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">range</span><span class="special">),</span>
              <span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">subrange</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">::</span><span class="identifier">const_iterator</span><span class="special">&gt;&gt;&gt;);</span>
</pre>
<p>
        Note that the <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1subrange.html" title="Struct template subrange">subrange</a></code>
        has the iterator type <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">::</span><span class="identifier">const_iterator</span></code>,
        because that's the iterator type passed to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa3a1f9c9842a7d78f838d924ec01f46a.html" title="Function template prefix_parse">prefix_parse()</a></code>.
        If we had passed <code class="computeroutput"><span class="keyword">char</span> <span class="keyword">const</span>
        <span class="special">*</span></code> iterators to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa3a1f9c9842a7d78f838d924ec01f46a.html" title="Function template prefix_parse">prefix_parse()</a></code>,
        that would have been the iterator type. The only exception to this comes
        from Unicode-aware parsing (see <a class="link" href="tutorial.html#boost_parser.tutorial.unicode_support" title="Unicode Support">Unicode
        Support</a>). In some of those cases, the iterator being used in the parse
        is not the one you passed. For instance, if you call <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa3a1f9c9842a7d78f838d924ec01f46a.html" title="Function template prefix_parse">prefix_parse()</a></code>
        with <code class="computeroutput"><span class="identifier">char8_t</span> <span class="special">*</span></code>
        iterators, it will create a UTF-8 to UTF-32 transcoding view, and parse the
        iterators of that view. In such a case, you'll get a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1subrange.html" title="Struct template subrange">subrange</a></code> whose iterator type
        is a transcoding iterator. When that happens, you can get the underlying
        iterator — the one you passed to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa3a1f9c9842a7d78f838d924ec01f46a.html" title="Function template prefix_parse">prefix_parse()</a></code>
        — by calling the <code class="computeroutput"><span class="special">.</span><span class="identifier">base</span><span class="special">()</span></code> member function on each transcoding iterator
        in the returned <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1subrange.html" title="Struct template subrange">subrange</a></code>.
      </p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">u8str</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">u8string</span><span class="special">(</span><span class="identifier">u8</span><span class="string">"1, 2, 3, 4, a, b, c"</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">u8first</span> <span class="special">=</span> <span class="identifier">u8str</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span>
<span class="keyword">auto</span> <span class="identifier">u8range</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">prefix_parse</span><span class="special">(</span><span class="identifier">u8first</span><span class="special">,</span> <span class="identifier">u8str</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">subrange_parser</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">u8range</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">u8range</span><span class="special">-&gt;</span><span class="identifier">begin</span><span class="special">().</span><span class="identifier">base</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">u8str</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">u8range</span><span class="special">-&gt;</span><span class="identifier">end</span><span class="special">().</span><span class="identifier">base</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">u8str</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()</span> <span class="special">+</span> <span class="number">10</span><span class="special">);</span>
</pre>
<h5>
<a name="boost_parser.tutorial.parsing_to_find_subranges.h1"></a>
        <span class="phrase"><a name="boost_parser.tutorial.parsing_to_find_subranges._globalname_alt__boost__parser__string_view___code__phrase_role__identifier__string_view__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.parsing_to_find_subranges._globalname_alt__boost__parser__string_view___code__phrase_role__identifier__string_view__phrase__phrase_role__special______phrase___code___globalname_">string_view[]</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a8890ba07e65b9e7b1b0f238e94498d.html" title="Global string_view">string_view[]</a></code> has very similar semantics
        to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3960485823df80f6a97f87e811cf7b.html" title="Global raw">raw[]</a></code>, except that it produces a
        <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string_view</span><span class="special">&lt;</span><span class="identifier">CharT</span><span class="special">&gt;</span></code>
        (where <code class="computeroutput"><span class="identifier">CharT</span></code> is the type
        of the underlying range begin parsed) instead of a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1subrange.html" title="Struct template subrange">subrange</a></code>. For this to work,
        the underlying range must be contiguous. Contiguity of iterators is not detectable
        before C++20, so this directive is only available in C++20 and later.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">int_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">%</span> <span class="char">','</span><span class="special">;</span>              <span class="comment">// ATTR(int_parser) is std::vector&lt;int&gt;</span>
<span class="keyword">auto</span> <span class="identifier">sv_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">string_view</span><span class="special">[</span><span class="identifier">int_parser</span><span class="special">];</span>  <span class="comment">// ATTR(sv_parser) is a string_view</span>

<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">str</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="string">"1, 2, 3, 4, a, b, c"</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span>
<span class="keyword">auto</span> <span class="identifier">sv1</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">prefix_parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">sv_parser</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">sv1</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(*</span><span class="identifier">sv1</span> <span class="special">==</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">substr</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">10</span><span class="special">));</span>

<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same_v</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">sv1</span><span class="special">),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span><span class="special">&gt;&gt;);</span>
</pre>
<p>
        Since <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a8890ba07e65b9e7b1b0f238e94498d.html" title="Global string_view">string_view[]</a></code> produces <code class="computeroutput"><span class="identifier">string_view</span></code>s,
        it cannot return transcoding iterators as described above for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3960485823df80f6a97f87e811cf7b.html" title="Global raw">raw[]</a></code>. If you parse a sequence of
        <code class="computeroutput"><span class="identifier">CharT</span></code> with <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a8890ba07e65b9e7b1b0f238e94498d.html" title="Global string_view">string_view[]</a></code>,
        you get exactly a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string_view</span><span class="special">&lt;</span><span class="identifier">CharT</span><span class="special">&gt;</span></code>.
        If the parse is using transcoding in the Unicode-aware path, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a8890ba07e65b9e7b1b0f238e94498d.html" title="Global string_view">string_view[]</a></code> will decompose the transcoding
        iterator as necessary. If you pass a transcoding view to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        or transcoding iterators to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa3a1f9c9842a7d78f838d924ec01f46a.html" title="Function template prefix_parse">prefix_parse()</a></code>,
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a8890ba07e65b9e7b1b0f238e94498d.html" title="Global string_view">string_view[]</a></code> will still see through the
        transcoding iterators without issue, and give you a <code class="computeroutput"><span class="identifier">string_view</span></code>
        of part of the underlying range.
      </p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">sv2</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"1, 2, 3, 4"</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf32</span><span class="special">,</span> <span class="identifier">sv_parser</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">sv2</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(*</span><span class="identifier">sv2</span> <span class="special">==</span> <span class="string">"1, 2, 3, 4"</span><span class="special">);</span>

<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same_v</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">sv2</span><span class="special">),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span><span class="special">&gt;&gt;);</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.the_parse_context"></a><a class="link" href="tutorial.html#boost_parser.tutorial.the_parse_context" title="The Parse Context">The Parse Context</a>
</h3></div></div></div>
<p>
        Now would be a good time to describe the parse context in some detail. Any
        semantic action that you write will need to use state in the parse context,
        so you need to know what's available.
      </p>
<p>
        The parse context is an object that stores the current state of the parse
        — the current- and end-iterators, the error handler, etc. Data may
        seem to be "added" to or "removed" from it at different
        times during the parse. For instance, when a parser <code class="computeroutput"><span class="identifier">p</span></code>
        with a semantic action <code class="computeroutput"><span class="identifier">a</span></code>
        succeeds, the context adds the attribute that <code class="computeroutput"><span class="identifier">p</span></code>
        produces to the parse context, then calls <code class="computeroutput"><span class="identifier">a</span></code>,
        passing it the context.
      </p>
<p>
        Though the context object appears to have things added to or removed from
        it, it does not. In reality, there is no one context object. Contexts are
        formed at various times during the parse, usually when starting a subparser.
        Each context is formed by taking the previous context and adding or changing
        members as needed to form a new context object. When the function containing
        the new context object returns, its context object (if any) is destructed.
        This is efficient to do, because the parse context has only about a dozen
        data members, and each data member is less than or equal to the size of a
        pointer. Copying the entire context when mutating the context is therefore
        fast. The context does no memory allocation.
      </p>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
          All these functions that take the parse context as their first parameter
          will find by found by Argument-Dependent Lookup. You will probably never
          need to qualify them with <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span></code>.
        </p></td></tr>
</table></div>
<h5>
<a name="boost_parser.tutorial.the_parse_context.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the_parse_context.accessors_for_data_that_are_always_available"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the_parse_context.accessors_for_data_that_are_always_available">Accessors
        for data that are always available</a>
      </h5>
<p>
        By convention, the names of all Boost.Parser functions that take a parse
        context, and are therefore intended for use inside semantic actions, contain
        a leading underscore.
      </p>
<h5>
<a name="boost_parser.tutorial.the_parse_context.h1"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___pass___code__phrase_role__identifier___pass__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___pass___code__phrase_role__identifier___pass__phrase__phrase_role__special______phrase___code___functionname_">_pass()</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a953a4fb7c71560e41b360fc7d51ee030.html" title="Function template _pass">_pass()</a></code> returns a reference to a
        <code class="computeroutput"><span class="keyword">bool</span></code> indicating the success
        of failure of the current parse. This can be used to force the current parse
        to pass or fail:
      </p>
<pre class="programlisting"><span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span>
    <span class="comment">// If the attribute fails to meet this predicate, fail the parse.</span>
    <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">necessary_condition</span><span class="special">(</span><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)))</span>
        <span class="identifier">_pass</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
        Note that for a semantic action to be executed, its associated parser must
        already have succeeded. So unless you previously wrote <code class="computeroutput"><span class="identifier">_pass</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span>
        <span class="special">=</span> <span class="keyword">false</span></code>
        within your action, <code class="computeroutput"><span class="identifier">_pass</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span>
        <span class="special">=</span> <span class="keyword">true</span></code>
        does nothing; it's redundant.
      </p>
<h5>
<a name="boost_parser.tutorial.the_parse_context.h2"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___begin___code__phrase_role__identifier___begin__phrase__phrase_role__special______phrase___code___functionname____functionname_alt__boost__parser___end___code__phrase_role__identifier___end__phrase__phrase_role__special______phrase___code___functionname__and__functionname_alt__boost__parser___where___code__phrase_role__identifier___where__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___begin___code__phrase_role__identifier___begin__phrase__phrase_role__special______phrase___code___functionname____functionname_alt__boost__parser___end___code__phrase_role__identifier___end__phrase__phrase_role__special______phrase___code___functionname__and__functionname_alt__boost__parser___where___code__phrase_role__identifier___where__phrase__phrase_role__special______phrase___code___functionname_">_begin(), _end()
        and _where()</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8190f95f16b08ebf1165ba5e207282f7.html" title="Function template _begin">_begin()</a></code> and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a63e0d17f609432179edef1a8ec6935ee.html" title="Function template _end">_end()</a></code>
        return the beginning and end of the range that you passed to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>, respectively. <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aeab1988a8b997f9eb81e5c910af70fe4.html" title="Function template _where">_where()</a></code> returns a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1subrange.html" title="Struct template subrange">subrange</a></code> indicating the bounds
        of the input matched by the current parse. <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aeab1988a8b997f9eb81e5c910af70fe4.html" title="Function template _where">_where()</a></code>
        can be useful if you just want to parse some text and return a result consisting
        of where certain elements are located, without producing any other attributes.
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aeab1988a8b997f9eb81e5c910af70fe4.html" title="Function template _where">_where()</a></code> can also be essential in
        tracking where things are located, to provide good diagnostics at a later
        point in the parse. Think mismatched tags in XML; if you parse a close-tag
        at the end of an element, and it does not match the open-tag, you want to
        produce an error message that mentions or shows both tags. Stashing <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aeab1988a8b997f9eb81e5c910af70fe4.html" title="Function template _where">_where</a><span class="special">(</span><span class="identifier">ctx</span><span class="special">).</span><span class="identifier">begin</span><span class="special">()</span></code>
        somewhere that is available to the close-tag parser will enable that. See
        <a class="link" href="tutorial.html#boost_parser.tutorial.error_handling_and_debugging" title="Error Handling and Debugging">Error
        Handling and Debugging</a> for an example of this.
      </p>
<h5>
<a name="boost_parser.tutorial.the_parse_context.h3"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___error_handler___code__phrase_role__identifier___error_handler__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___error_handler___code__phrase_role__identifier___error_handler__phrase__phrase_role__special______phrase___code___functionname_">_error_handler()</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a9c8ae49775523bb75e651c7b4eddcc99.html" title="Function template _error_handler">_error_handler()</a></code> returns a reference to the
        error handler associated with the parser passed to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>.
        Using <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a9c8ae49775523bb75e651c7b4eddcc99.html" title="Function template _error_handler">_error_handler()</a></code>, you can generate errors
        and warnings from within your semantic actions. See <a class="link" href="tutorial.html#boost_parser.tutorial.error_handling_and_debugging" title="Error Handling and Debugging">Error
        Handling and Debugging</a> for concrete examples.
      </p>
<h5>
<a name="boost_parser.tutorial.the_parse_context.h4"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the_parse_context.accessors_for_data_that_are_only_sometimes_available"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the_parse_context.accessors_for_data_that_are_only_sometimes_available">Accessors
        for data that are only sometimes available</a>
      </h5>
<h5>
<a name="boost_parser.tutorial.the_parse_context.h5"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___attr___code__phrase_role__identifier___attr__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___attr___code__phrase_role__identifier___attr__phrase__phrase_role__special______phrase___code___functionname_">_attr()</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a71e5796c9397af8c18c3dfe6ff902d65.html" title="Function template _attr">_attr()</a></code> returns a reference to the
        value of the current parser's attribute. It is available only when the current
        parser's parse is successful. If the parser has no semantic action, no attribute
        gets added to the parse context. It can be used to read and write the current
        parser's attribute:
      </p>
<pre class="programlisting"><span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="special">}</span>
</pre>
<p>
        If the current parser has no attribute, a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1none.html" title="Struct none">none</a></code> is returned.
      </p>
<h5>
<a name="boost_parser.tutorial.the_parse_context.h6"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___val___code__phrase_role__identifier___val__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___val___code__phrase_role__identifier___val__phrase__phrase_role__special______phrase___code___functionname_">_val()</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3786fbbcb7262b8da0b87e7ac30e37.html" title="Function _val">_val()</a></code> returns a reference to the
        value of the attribute of the current rule being used to parse (if any),
        and is available even before the rule's parse is successful. It can be used
        to set the current rule's attribute, even from a parser that is a subparser
        inside the rule. Let's say we're writing a parser with a semantic action
        that is within a rule. If we want to set the current rule's value to some
        function of subparser's attribute, we would write this semantic action:
      </p>
<pre class="programlisting"><span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">some_function</span><span class="special">(</span><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">));</span> <span class="special">}</span>
</pre>
<p>
        If there is no current rule, or the current rule has no attribute, a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1none.html" title="Struct none">none</a></code>
        is returned.
      </p>
<p>
        You need to use <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3786fbbcb7262b8da0b87e7ac30e37.html" title="Function _val">_val()</a></code> in cases where the default
        attribute for a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>'s
        parser is not directly compatible with the attribute type of the <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>.
        In these cases, you'll need to write some code like the example above to
        compute the <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>'s
        attribute from the <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>'s
        parser's generated attribute. For more info on <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>, see the next page, and
        <a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules" title="More About Rules">More About Rules</a>.
      </p>
<h5>
<a name="boost_parser.tutorial.the_parse_context.h7"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___globals___code__phrase_role__identifier___globals__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___globals___code__phrase_role__identifier___globals__phrase__phrase_role__special______phrase___code___functionname_">_globals()</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aedbd47dbeefeba9d1e3f8ed71f41aefc.html" title="Function template _globals">_globals()</a></code> returns a reference to a
        user-supplied object that contains whatever data you want to use during the
        parse. The "globals" for a parse is an object — typically
        a struct — that you give to the top-level parser. Then you can use
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aedbd47dbeefeba9d1e3f8ed71f41aefc.html" title="Function template _globals">_globals()</a></code> to access it at any time
        during the parse. We'll see how globals get associated with the top-level
        parser in <a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api" title="The parse() API">The <code class="computeroutput"><span class="identifier">parse</span><span class="special">()</span></code>
        API</a> later. As an example, say that you have an early part of the parse
        that needs to record some black-listed values, and that later parts of the
        parse might need to parse values, failing the parse if they see the black-listed
        values. In the early part of the parse, you could write something like this.
      </p>
<pre class="programlisting"><span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span>
    <span class="comment">// black_list is a std::unordered_set.</span>
    <span class="identifier">_globals</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">).</span><span class="identifier">black_list</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">));</span>
<span class="special">}</span>
</pre>
<p>
        Later in the parse, you could then use <code class="computeroutput"><span class="identifier">black_list</span></code>
        to check values as they are parsed.
      </p>
<pre class="programlisting"><span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">_globals</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">).</span><span class="identifier">black_list</span><span class="special">.</span><span class="identifier">contains</span><span class="special">(</span><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)))</span>
        <span class="identifier">_pass</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<h5>
<a name="boost_parser.tutorial.the_parse_context.h8"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___locals___code__phrase_role__identifier___locals__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___locals___code__phrase_role__identifier___locals__phrase__phrase_role__special______phrase___code___functionname_">_locals()</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aea9a85108e6af1280eccd9135584938d.html" title="Function template _locals">_locals()</a></code> returns a reference to one
        or more values that are local to the current rule being parsed, if any. If
        there are two or more local values, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aea9a85108e6af1280eccd9135584938d.html" title="Function template _locals">_locals()</a></code>
        returns a reference to a <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a></code>. Rules with locals are
        something we haven't gotten to yet (see <a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules" title="More About Rules">More
        About Rules</a>), but for now all you need to know is that you can provide
        a template parameter (<code class="computeroutput"><span class="identifier">LocalState</span></code>)
        to <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>,
        and the rule will default construct an object of that type for use within
        the rule. You access it via <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aea9a85108e6af1280eccd9135584938d.html" title="Function template _locals">_locals()</a></code>:
      </p>
<pre class="programlisting"><span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span>
    <span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">local</span> <span class="special">=</span> <span class="identifier">_locals</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">);</span>
    <span class="comment">// Use local here.  If 'local' is a hana::tuple, access its members like this:</span>
    <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">hana</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
    <span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">first_element</span> <span class="special">=</span> <span class="identifier">local</span><span class="special">[</span><span class="number">0</span><span class="identifier">_c</span><span class="special">];</span>
    <span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">second_element</span> <span class="special">=</span> <span class="identifier">local</span><span class="special">[</span><span class="number">1</span><span class="identifier">_c</span><span class="special">];</span>
<span class="special">}</span>
</pre>
<p>
        If there is no current rule, or the current rule has no locals, a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1none.html" title="Struct none">none</a></code>
        is returned.
      </p>
<h5>
<a name="boost_parser.tutorial.the_parse_context.h9"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___params___code__phrase_role__identifier___params__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___params___code__phrase_role__identifier___params__phrase__phrase_role__special______phrase___code___functionname_">_params()</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a376d70158bb5f8ce13cfcee77bbce958.html" title="Function template _params">_params()</a></code>, like <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aea9a85108e6af1280eccd9135584938d.html" title="Function template _locals">_locals()</a></code>,
        applies to the current rule being used to parse, if any (see <a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules" title="More About Rules">More
        About Rules</a>). It also returns a reference to a single value, if the
        current rule has only one parameter, or a <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a></code> of multiple values if
        the current rule has multiple parameters. If there is no current rule, or
        the current rule has no parameters, a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1none.html" title="Struct none">none</a></code> is returned.
      </p>
<p>
        Unlike with <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aea9a85108e6af1280eccd9135584938d.html" title="Function template _locals">_locals()</a></code>, you <span class="bold"><strong>do
        not</strong></span> provide a template parameter to <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>. Instead you call the
        <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>'s
        <code class="computeroutput"><span class="identifier">with</span><span class="special">()</span></code>
        member function (again, see <a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules" title="More About Rules">More
        About Rules</a>).
      </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1none.html" title="Struct none">none</a></code>
          is a type that is used as a return value in Boost.Parser for parse context
          accessors. <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1none.html" title="Struct none">none</a></code>
          is convertible to anything that has a default constructor, convertible
          from anything, assignable form anything, and has templated overloads for
          all the overloadable operators. The intention is that a misuse of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3786fbbcb7262b8da0b87e7ac30e37.html" title="Function _val">_val()</a></code>, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aedbd47dbeefeba9d1e3f8ed71f41aefc.html" title="Function template _globals">_globals()</a></code>,
          etc. should compile, and produce an assertion at runtime. Experience has
          shown that using a debugger for investigating the stack that leads to your
          mistake is a far better user experience than sifting through compiler diagnostics.
          See the <a class="link" href="rationale.html" title="Rationale">Rationale</a> section
          for a more detailed explanation.
        </p></td></tr>
</table></div>
<h5>
<a name="boost_parser.tutorial.the_parse_context.h10"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___no_case___code__phrase_role__identifier___no_case__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the_parse_context._functionname_alt__boost__parser___no_case___code__phrase_role__identifier___no_case__phrase__phrase_role__special______phrase___code___functionname_"><code class="computeroutput">_no_case()</code></a>
      </h5>
<p>
        <code class="computeroutput">_no_case()</code> returns <code class="computeroutput"><span class="keyword">true</span></code>
        if the current parse context is inside one or more (possibly nested) <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a3f4e39c08f5f3a79750e7bcf8b542fdd.html" title="Global no_case">no_case[]</a></code> directives. I don't have a
        use case for this, but if I didn't expose it, it would be the only thing
        in the context that you could not examine from inside a semantic action.
        It was easy to add, so I did.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.rule_parsers"></a><a class="link" href="tutorial.html#boost_parser.tutorial.rule_parsers" title="Rule Parsers">Rule Parsers</a>
</h3></div></div></div>
<p>
        This example is very similar to the others we've seen so far. This one is
        different only because it uses a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>. As an analogy, think
        of a parser like <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>
        or <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6e37283853b49605ec05b4a1969eaaac.html" title="Global double_">double_</a></code>
        as an individual line of code, and a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code> as a function. Like a
        function, a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>
        has its own name, and can even be forward declared. Here is how we define
        a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>,
        which is analogous to forward declaring a function:
      </p>
<p>
</p>
<pre class="programlisting"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">doubles</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;&gt;</span> <span class="identifier">doubles</span> <span class="special">=</span> <span class="string">"doubles"</span><span class="special">;</span>
</pre>
<p>
      </p>
<p>
        This declares the rule itself. The <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code> is a parser, and we can
        immediately use it in other parsers. That definition is pretty dense; take
        note of these things:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            The first template parameter is a tag type <code class="computeroutput"><span class="keyword">struct</span>
            <span class="identifier">doubles</span></code>. Here we've declared
            the tag type and used it all in one go; you can also use a previously
            declared tag type.
          </li>
<li class="listitem">
            The second template parameter is the attribute type of the parser. If
            you don't provide this, the rule will have no attribute.
          </li>
<li class="listitem">
            This rule object itself is called <code class="computeroutput"><span class="identifier">doubles</span></code>.
          </li>
<li class="listitem">
            We've given <code class="computeroutput"><span class="identifier">doubles</span></code> the
            diagnstic text <code class="computeroutput"><span class="string">"doubles"</span></code>
            so that Boost.Parser knows how to refer to it when producing a trace
            of the parser during debugging.
          </li>
</ul></div>
<p>
        Ok, so if <code class="computeroutput"><span class="identifier">doubles</span></code> is a parser,
        what does it do? We define the rule's behavior by defining a separate parser
        that by now should look pretty familiar:
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">doubles_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span> <span class="special">%</span> <span class="char">','</span><span class="special">;</span>
</pre>
<p>
      </p>
<p>
        This is analogous to writing a definition for a forward-declared function.
        Note that we used the name <code class="computeroutput"><span class="identifier">doubles_def</span></code>.
        Right now, the <code class="computeroutput"><span class="identifier">doubles</span></code> rule
        parser and the <code class="computeroutput"><span class="identifier">doubles_def</span></code>
        non-rule parser have no connection to each other. That's intentional —
        we want to be able to define them separately. To connect them, we declare
        functions with an interface that Boost.Parser understands, and use the tag
        type <code class="computeroutput"><span class="keyword">struct</span> <span class="identifier">doubles</span></code>
        to connect them together. We use a macro for that:
      </p>
<p>
</p>
<pre class="programlisting"><span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">doubles</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        This macro expands to the code necessary to make the rule <code class="computeroutput"><span class="identifier">doubles</span></code>
        and its parser <code class="computeroutput"><span class="identifier">doubles_def</span></code>
        work together. The <code class="computeroutput"><span class="identifier">_def</span></code> suffix
        is a naming convention that this macro relies on to work. The tag type allows
        the rule parser, <code class="computeroutput"><span class="identifier">doubles</span></code>,
        to call one of these overloads when used as a parser.
      </p>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/parser_8hpp_1a415c73d97c52d81aa79038f959dd3020.html" title="Macro BOOST_PARSER_DEFINE_RULES">BOOST_PARSER_DEFINE_RULES</a></code>
        expands to two overloads of a function called <code class="computeroutput"><span class="identifier">parse_rule</span><span class="special">()</span></code>. In the case above, the overloads each
        take a <code class="computeroutput"><span class="keyword">struct</span> <span class="identifier">doubles</span></code>
        parameter (to distinguish them from the other overloads of <code class="computeroutput"><span class="identifier">parse_rule</span><span class="special">()</span></code>
        for other rules) and parse using <code class="computeroutput"><span class="identifier">doubles_def</span></code>.
        You will never need to call any overload of <code class="computeroutput"><span class="identifier">parse_rule</span><span class="special">()</span></code> yourself; it is used internally by the
        parser that implements <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>, <code class="computeroutput"><span class="identifier">rule_parser</span></code>.
      </p>
<p>
        Here is the definition of the macro that is expanded for each rule:
      </p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_PARSER_DEFINE_IMPL</span><span class="special">(</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">rule_name_</span><span class="special">)</span>                                <span class="special">\</span>
    <span class="keyword">template</span><span class="special">&lt;</span>                                                                  <span class="special">\</span>
        <span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">,</span>                                                         <span class="special">\</span>
        <span class="keyword">typename</span> <span class="identifier">Sentinel</span><span class="special">,</span>                                                     <span class="special">\</span>
        <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">,</span>                                                      <span class="special">\</span>
        <span class="keyword">typename</span> <span class="identifier">SkipParser</span><span class="special">&gt;</span>                                                   <span class="special">\</span>
    <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">rule_name_</span><span class="special">)::</span><span class="identifier">parser_type</span><span class="special">::</span><span class="identifier">attr_type</span> <span class="identifier">parse_rule</span><span class="special">(</span>                   <span class="special">\</span>
        <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">rule_name_</span><span class="special">)::</span><span class="identifier">parser_type</span><span class="special">::</span><span class="identifier">tag_type</span> <span class="special">*,</span>                         <span class="special">\</span>
        <span class="identifier">Iter</span> <span class="special">&amp;</span> <span class="identifier">first</span><span class="special">,</span>                                                          <span class="special">\</span>
        <span class="identifier">Sentinel</span> <span class="identifier">last</span><span class="special">,</span>                                                         <span class="special">\</span>
        <span class="identifier">Context</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">context</span><span class="special">,</span>                                               <span class="special">\</span>
        <span class="identifier">SkipParser</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">skip</span><span class="special">,</span>                                               <span class="special">\</span>
        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">flags</span> <span class="identifier">flags</span><span class="special">,</span>                                    <span class="special">\</span>
        <span class="keyword">bool</span> <span class="special">&amp;</span> <span class="identifier">success</span><span class="special">,</span>                                                        <span class="special">\</span>
        <span class="keyword">bool</span> <span class="special">&amp;</span> <span class="identifier">dont_assign</span><span class="special">)</span>                                                    <span class="special">\</span>
    <span class="special">{</span>                                                                          <span class="special">\</span>
        <span class="keyword">auto</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="identifier">BOOST_PARSER_PP_CAT</span><span class="special">(</span><span class="identifier">rule_name_</span><span class="special">,</span> <span class="identifier">_def</span><span class="special">);</span>           <span class="special">\</span>
        <span class="keyword">using</span> <span class="identifier">attr_t</span> <span class="special">=</span>                                                         <span class="special">\</span>
            <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">parser</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">success</span><span class="special">));</span>      <span class="special">\</span>
        <span class="keyword">using</span> <span class="identifier">attr_type</span> <span class="special">=</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">rule_name_</span><span class="special">)::</span><span class="identifier">parser_type</span><span class="special">::</span><span class="identifier">attr_type</span><span class="special">;</span>        <span class="special">\</span>
        <span class="keyword">if</span> <span class="keyword">constexpr</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">is_nope_v</span><span class="special">&lt;</span><span class="identifier">attr_t</span><span class="special">&gt;)</span> <span class="special">{</span>              <span class="special">\</span>
            <span class="identifier">dont_assign</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>                                                <span class="special">\</span>
            <span class="identifier">parser</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">success</span><span class="special">);</span>                <span class="special">\</span>
            <span class="keyword">return</span> <span class="special">{};</span>                                                         <span class="special">\</span>
        <span class="special">}</span> <span class="keyword">else</span> <span class="keyword">if</span> <span class="keyword">constexpr</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same_v</span><span class="special">&lt;</span><span class="identifier">attr_type</span><span class="special">,</span> <span class="identifier">attr_t</span><span class="special">&gt;)</span> <span class="special">{</span>              <span class="special">\</span>
            <span class="keyword">return</span> <span class="identifier">parser</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">success</span><span class="special">);</span>         <span class="special">\</span>
        <span class="special">}</span> <span class="keyword">else</span> <span class="keyword">if</span> <span class="keyword">constexpr</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_constructible_v</span><span class="special">&lt;</span><span class="identifier">attr_type</span><span class="special">,</span> <span class="identifier">attr_t</span><span class="special">&gt;)</span> <span class="special">{</span>     <span class="special">\</span>
            <span class="keyword">return</span> <span class="identifier">attr_type</span><span class="special">(</span>                                                  <span class="special">\</span>
                <span class="identifier">parser</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">success</span><span class="special">));</span>           <span class="special">\</span>
        <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>                                                               <span class="special">\</span>
            <span class="identifier">attr_type</span> <span class="identifier">attr</span><span class="special">{};</span>                                                  <span class="special">\</span>
            <span class="identifier">parser</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">success</span><span class="special">,</span> <span class="identifier">attr</span><span class="special">);</span>          <span class="special">\</span>
            <span class="keyword">return</span> <span class="identifier">attr</span><span class="special">;</span>                                                       <span class="special">\</span>
        <span class="special">}</span>                                                                      <span class="special">\</span>
    <span class="special">}</span>                                                                          <span class="special">\</span>
                                                                               <span class="special">\</span>
    <span class="keyword">template</span><span class="special">&lt;</span>                                                                  <span class="special">\</span>
        <span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">,</span>                                                         <span class="special">\</span>
        <span class="keyword">typename</span> <span class="identifier">Sentinel</span><span class="special">,</span>                                                     <span class="special">\</span>
        <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">,</span>                                                      <span class="special">\</span>
        <span class="keyword">typename</span> <span class="identifier">SkipParser</span><span class="special">,</span>                                                   <span class="special">\</span>
        <span class="keyword">typename</span> <span class="identifier">Attribute</span><span class="special">&gt;</span>                                                    <span class="special">\</span>
    <span class="keyword">void</span> <span class="identifier">parse_rule</span><span class="special">(</span>                                                           <span class="special">\</span>
        <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">rule_name_</span><span class="special">)::</span><span class="identifier">parser_type</span><span class="special">::</span><span class="identifier">tag_type</span> <span class="special">*,</span>                         <span class="special">\</span>
        <span class="identifier">Iter</span> <span class="special">&amp;</span> <span class="identifier">first</span><span class="special">,</span>                                                          <span class="special">\</span>
        <span class="identifier">Sentinel</span> <span class="identifier">last</span><span class="special">,</span>                                                         <span class="special">\</span>
        <span class="identifier">Context</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">context</span><span class="special">,</span>                                               <span class="special">\</span>
        <span class="identifier">SkipParser</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">skip</span><span class="special">,</span>                                               <span class="special">\</span>
        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">flags</span> <span class="identifier">flags</span><span class="special">,</span>                                    <span class="special">\</span>
        <span class="keyword">bool</span> <span class="special">&amp;</span> <span class="identifier">success</span><span class="special">,</span>                                                        <span class="special">\</span>
        <span class="keyword">bool</span> <span class="special">&amp;</span> <span class="identifier">dont_assign</span><span class="special">,</span>                                                    <span class="special">\</span>
        <span class="identifier">Attribute</span> <span class="special">&amp;</span> <span class="identifier">retval</span><span class="special">)</span>                                                    <span class="special">\</span>
    <span class="special">{</span>                                                                          <span class="special">\</span>
        <span class="keyword">auto</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="identifier">BOOST_PARSER_PP_CAT</span><span class="special">(</span><span class="identifier">rule_name_</span><span class="special">,</span> <span class="identifier">_def</span><span class="special">);</span>           <span class="special">\</span>
        <span class="keyword">using</span> <span class="identifier">attr_t</span> <span class="special">=</span>                                                         <span class="special">\</span>
            <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">parser</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">success</span><span class="special">));</span>      <span class="special">\</span>
        <span class="keyword">if</span> <span class="keyword">constexpr</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">is_nope_v</span><span class="special">&lt;</span><span class="identifier">attr_t</span><span class="special">&gt;)</span> <span class="special">{</span>              <span class="special">\</span>
            <span class="identifier">parser</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">success</span><span class="special">);</span>                <span class="special">\</span>
        <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>                                                               <span class="special">\</span>
            <span class="identifier">parser</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">success</span><span class="special">,</span> <span class="identifier">retval</span><span class="special">);</span>        <span class="special">\</span>
        <span class="special">}</span>                                                                      <span class="special">\</span>
    <span class="special">}</span>
</pre>
<p>
      </p>
<p>
        Now that we have the <code class="computeroutput"><span class="identifier">doubles</span></code>
        parser, we can use it like we might any other parser:
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">doubles</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        The full program:
      </p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">parser</span><span class="special">/</span><span class="identifier">parser</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">deque</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>


<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>


<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">doubles</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;&gt;</span> <span class="identifier">doubles</span> <span class="special">=</span> <span class="string">"doubles"</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">doubles_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span> <span class="special">%</span> <span class="char">','</span><span class="special">;</span>
<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">doubles</span><span class="special">);</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Please enter a list of doubles, separated by commas. "</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">input</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">,</span> <span class="identifier">input</span><span class="special">);</span>

    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">doubles</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>

    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"You entered:\n"</span><span class="special">;</span>
        <span class="keyword">for</span> <span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span> <span class="special">:</span> <span class="special">*</span><span class="identifier">result</span><span class="special">)</span> <span class="special">{</span>
            <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
        <span class="special">}</span>
    <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Parse failure.\n"</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        All this is intended to introduce the notion of <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>. It still may be a bit
        unclear why you would want to use <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>. The use cases for, and
        lots of detail about, <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code> is in a later section,
        <a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules" title="More About Rules">More About Rules</a>.
      </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          The existence of <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>
          means that will probably never have to write a low-level parser. You can
          just put existing parsers together into <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code> instead.
        </p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.parsing_into__struct_s_and__class_es"></a><a class="link" href="tutorial.html#boost_parser.tutorial.parsing_into__struct_s_and__class_es" title="Parsing into structs and classes">Parsing
      into <code class="computeroutput"><span class="keyword">struct</span></code>s and <code class="computeroutput"><span class="keyword">class</span></code>es</a>
</h3></div></div></div>
<p>
        So far, we've seen only simple parsers that parse the same value repeatedly
        (with or without commas and spaces). It's also very common to parse a few
        values in a specific sequence. Let's say you want to parse an employee record.
        Here's a parser you might write:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">employee_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="string">"employee"</span><span class="special">)</span>
    <span class="special">&gt;&gt;</span> <span class="char">'{'</span>
    <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
    <span class="special">&gt;&gt;</span> <span class="identifier">quoted_string</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
    <span class="special">&gt;&gt;</span> <span class="identifier">quoted_string</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
    <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span>
    <span class="special">&gt;&gt;</span> <span class="char">'}'</span><span class="special">;</span>
</pre>
<p>
        The attribute type for <code class="computeroutput"><span class="identifier">employee_parser</span></code>
        is <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span></code>.
        That's great, in that you got all the parsed data for the record without
        having to write any semantic actions. It's not so great that you now have
        to get all the individual elements out by their indices, using <code class="computeroutput"><span class="identifier">get</span><span class="special">()</span></code>.
        It would be much nicer to parse into the final data structure that your program
        is going to use. This is often some <code class="computeroutput"><span class="keyword">struct</span></code>
        or <code class="computeroutput"><span class="keyword">class</span></code>. Boost.Parser supports
        parsing into arbitrary aggregate <code class="computeroutput"><span class="keyword">struct</span></code>s,
        and non-aggregates that are constructible from the tuple at hand.
      </p>
<h5>
<a name="boost_parser.tutorial.parsing_into__struct_s_and__class_es.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.parsing_into__struct_s_and__class_es.aggregate_types_as_attributes"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.parsing_into__struct_s_and__class_es.aggregate_types_as_attributes">Aggregate
        types as attributes</a>
      </h5>
<p>
        If we have a <code class="computeroutput"><span class="keyword">struct</span></code> that has
        data members of the same types listed in the <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a></code> attribute type for <code class="computeroutput"><span class="identifier">employee_parser</span></code>, it would be nice to parse
        directly into it, instead of parsing into a tuple and then constructing our
        <code class="computeroutput"><span class="keyword">struct</span></code> later. Fortunately, this
        just works in Boost.Parser. Here is an example of parsing straight into a
        compatible aggregate type.
      </p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">parser</span><span class="special">/</span><span class="identifier">parser</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>


<span class="keyword">struct</span> <span class="identifier">employee</span>
<span class="special">{</span>
    <span class="keyword">int</span> <span class="identifier">age</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">surname</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">forename</span><span class="special">;</span>
    <span class="keyword">double</span> <span class="identifier">salary</span><span class="special">;</span>
<span class="special">};</span>

<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Enter employee record. "</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">input</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">,</span> <span class="identifier">input</span><span class="special">);</span>

    <span class="keyword">auto</span> <span class="identifier">quoted_string</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</span> <span class="special">&gt;&gt;</span> <span class="special">+(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="char">'"'</span><span class="special">];</span>
    <span class="keyword">auto</span> <span class="identifier">employee_p</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="string">"employee"</span><span class="special">)</span>
        <span class="special">&gt;&gt;</span> <span class="char">'{'</span>
        <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
        <span class="special">&gt;&gt;</span> <span class="identifier">quoted_string</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
        <span class="special">&gt;&gt;</span> <span class="identifier">quoted_string</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
        <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span>
        <span class="special">&gt;&gt;</span> <span class="char">'}'</span><span class="special">;</span>

    <span class="identifier">employee</span> <span class="identifier">record</span><span class="special">;</span>
    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">employee_p</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">,</span> <span class="identifier">record</span><span class="special">);</span>

    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"You entered:\nage:      "</span> <span class="special">&lt;&lt;</span> <span class="identifier">record</span><span class="special">.</span><span class="identifier">age</span>
                  <span class="special">&lt;&lt;</span> <span class="string">"\nsurname:  "</span> <span class="special">&lt;&lt;</span> <span class="identifier">record</span><span class="special">.</span><span class="identifier">surname</span>
                  <span class="special">&lt;&lt;</span> <span class="string">"\nforename: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">record</span><span class="special">.</span><span class="identifier">forename</span>
                  <span class="special">&lt;&lt;</span> <span class="string">"\nsalary  : "</span> <span class="special">&lt;&lt;</span> <span class="identifier">record</span><span class="special">.</span><span class="identifier">salary</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
    <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Parse failure.\n"</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        Unfortunately, this is taking advantage of the loose attribute assignment
        logic; the <code class="computeroutput"><span class="identifier">employee_parser</span></code>
        parser still has a <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a></code>
        attribute. See <a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api" title="The parse() API">The
        <code class="computeroutput"><span class="identifier">parse</span><span class="special">()</span></code>
        API</a> for a description of attribute out-param compatibility.
      </p>
<p>
        For this reason, it's even more common to want to make a rule that returns
        a specific type like <code class="computeroutput"><span class="identifier">employee</span></code>.
        Just by giving the rule a <code class="computeroutput"><span class="keyword">struct</span></code>
        type, we make sure that this parser always generates an <code class="computeroutput"><span class="identifier">employee</span></code>
        struct as its attribute, no matter where it is in the parse. If we made a
        simple parser <code class="computeroutput"><span class="identifier">P</span></code> that uses
        the <code class="computeroutput"><span class="identifier">employee_p</span></code> rule, like
        <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="keyword">int</span> <span class="special">&gt;&gt;</span> <span class="identifier">employee_p</span></code>, <code class="computeroutput"><span class="identifier">P</span></code>'s
        attribute type would be <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">employee</span><span class="special">&gt;</span></code>.
      </p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">parser</span><span class="special">/</span><span class="identifier">parser</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>


<span class="keyword">struct</span> <span class="identifier">employee</span>
<span class="special">{</span>
    <span class="keyword">int</span> <span class="identifier">age</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">surname</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">forename</span><span class="special">;</span>
    <span class="keyword">double</span> <span class="identifier">salary</span><span class="special">;</span>
<span class="special">};</span>

<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">quoted_string</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">quoted_string</span> <span class="special">=</span> <span class="string">"quoted name"</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">employee_p</span><span class="special">,</span> <span class="identifier">employee</span><span class="special">&gt;</span> <span class="identifier">employee_p</span> <span class="special">=</span> <span class="string">"employee"</span><span class="special">;</span>

<span class="keyword">auto</span> <span class="identifier">quoted_string_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</span> <span class="special">&gt;&gt;</span> <span class="special">+(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="char">'"'</span><span class="special">];</span>
<span class="keyword">auto</span> <span class="identifier">employee_p_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="string">"employee"</span><span class="special">)</span>
    <span class="special">&gt;&gt;</span> <span class="char">'{'</span>
    <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
    <span class="special">&gt;&gt;</span> <span class="identifier">quoted_string</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
    <span class="special">&gt;&gt;</span> <span class="identifier">quoted_string</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
    <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span>
    <span class="special">&gt;&gt;</span> <span class="char">'}'</span><span class="special">;</span>

<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">quoted_string</span><span class="special">,</span> <span class="identifier">employee_p</span><span class="special">);</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Enter employee record. "</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">input</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">,</span> <span class="identifier">input</span><span class="special">);</span>

    <span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_aggregate_v</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">employee</span> <span class="special">&amp;&gt;&gt;);</span>

    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">employee_p</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>

    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"You entered:\nage:      "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span><span class="special">-&gt;</span><span class="identifier">age</span>
                  <span class="special">&lt;&lt;</span> <span class="string">"\nsurname:  "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span><span class="special">-&gt;</span><span class="identifier">surname</span>
                  <span class="special">&lt;&lt;</span> <span class="string">"\nforename: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span><span class="special">-&gt;</span><span class="identifier">forename</span>
                  <span class="special">&lt;&lt;</span> <span class="string">"\nsalary  : "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span><span class="special">-&gt;</span><span class="identifier">salary</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
    <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Parse failure.\n"</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        Just as you can pass a <code class="computeroutput"><span class="keyword">struct</span></code>
        as an out-param to <code class="computeroutput"><span class="identifier">parse</span><span class="special">()</span></code> when the parser's attribute type is a tuple,
        you can also pass a tuple as an out-param to <code class="computeroutput"><span class="identifier">parse</span><span class="special">()</span></code> when the parser's attribute type is a struct:
      </p>
<pre class="programlisting"><span class="comment">// Using the employee_p rule from above, with attribute type employee...</span>
<code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a></code><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">tup</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">employee_p</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">,</span> <span class="identifier">tup</span><span class="special">);</span> <span class="comment">// Ok!</span>
</pre>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          This automatic use of <code class="computeroutput"><span class="keyword">struct</span></code>s
          as if they were tuples depends on a bit of metaprogramming. Due to compiler
          limits, the metaprogram that detects the number of data members of a <code class="computeroutput"><span class="keyword">struct</span></code> is limited to a maximum number of
          members. Fortunately, that limit is configurable; see <code class="computeroutput"><a class="link" href="../doxygen/headers/config_8hpp_1a4a28f30fd27c316404cdb61d859ae6c5.html" title="Macro BOOST_PARSER_MAX_AGGREGATE_SIZE">BOOST_PARSER_MAX_AGGREGATE_SIZE</a></code>.
        </p></td></tr>
</table></div>
<h5>
<a name="boost_parser.tutorial.parsing_into__struct_s_and__class_es.h1"></a>
        <span class="phrase"><a name="boost_parser.tutorial.parsing_into__struct_s_and__class_es.general__code__phrase_role__keyword__class__phrase___code__types_as_attributes"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.parsing_into__struct_s_and__class_es.general__code__phrase_role__keyword__class__phrase___code__types_as_attributes">General
        <code class="computeroutput"><span class="keyword">class</span></code> types as attributes</a>
      </h5>
<p>
        Many times you don't have an aggregate struct that you want to produce from
        your parse. It would be even nicer than the aggregate code above if Boost.Parser
        could detect that the members of a tuple that is produced as an attribute
        are usable as the arguments to some type's constructor. So, Boost.Parser
        does that.
      </p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">parser</span><span class="special">/</span><span class="identifier">parser</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>


<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Enter a string followed by two unsigned integers. "</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">input</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">,</span> <span class="identifier">input</span><span class="special">);</span>

    <span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">string_uint_uint</span> <span class="special">=</span>
        <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">' '</span><span class="special">)]</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">uint_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">uint_</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">string_from_parse</span><span class="special">;</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">string_uint_uint</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">,</span> <span class="identifier">string_from_parse</span><span class="special">))</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"That yields this string: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">string_from_parse</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
    <span class="keyword">else</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Parse failure.\n"</span><span class="special">;</span>

    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Enter an unsigned integer followed by a string. "</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">,</span> <span class="identifier">input</span><span class="special">);</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">input</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>

    <span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">uint_string</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">uint_</span> <span class="special">&gt;&gt;</span> <span class="special">+</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">vector_from_parse</span><span class="special">;</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">uint_string</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">,</span> <span class="identifier">vector_from_parse</span><span class="special">))</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"That yields this vector of strings:\n"</span><span class="special">;</span>
        <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span> <span class="special">&amp;&amp;</span> <span class="identifier">str</span> <span class="special">:</span> <span class="identifier">vector_from_parse</span><span class="special">)</span> <span class="special">{</span>
            <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"  '"</span> <span class="special">&lt;&lt;</span> <span class="identifier">str</span> <span class="special">&lt;&lt;</span> <span class="string">"'\n"</span><span class="special">;</span>
        <span class="special">}</span>
    <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Parse failure.\n"</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        Let's look at the first parse.
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">string_uint_uint</span> <span class="special">=</span>
    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">' '</span><span class="special">)]</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">uint_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">uint_</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">string_from_parse</span><span class="special">;</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">string_uint_uint</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">,</span> <span class="identifier">string_from_parse</span><span class="special">))</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"That yields this string: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">string_from_parse</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="keyword">else</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Parse failure.\n"</span><span class="special">;</span>
</pre>
<p>
      </p>
<p>
        Here, we use the parser <code class="computeroutput"><span class="identifier">string_uint_uint</span></code>,
        which produces a <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">unsigned</span>
        <span class="keyword">int</span><span class="special">&gt;</span></code>
        attribute. When we try to parse that into an out-param <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
        attribute, it just works. This is because <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
        has a constructor that takes a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>,
        an offset, and a length. Here's the other parse:
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">uint_string</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">uint_</span> <span class="special">&gt;&gt;</span> <span class="special">+</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">vector_from_parse</span><span class="special">;</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">uint_string</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">,</span> <span class="identifier">vector_from_parse</span><span class="special">))</span> <span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"That yields this vector of strings:\n"</span><span class="special">;</span>
    <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span> <span class="special">&amp;&amp;</span> <span class="identifier">str</span> <span class="special">:</span> <span class="identifier">vector_from_parse</span><span class="special">)</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"  '"</span> <span class="special">&lt;&lt;</span> <span class="identifier">str</span> <span class="special">&lt;&lt;</span> <span class="string">"'\n"</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Parse failure.\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        Now we have the parser <code class="computeroutput"><span class="identifier">uint_string</span></code>,
        which produces <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span></code>
        attribute — the two <code class="computeroutput"><span class="keyword">char</span></code>s
        at the end combine into a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
        Those two values can be used to construct a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span></code>, via the count, <code class="computeroutput"><span class="identifier">T</span></code>
        constructor.
      </p>
<p>
        Just like with using aggregates in place of tuples, non-aggregate <code class="computeroutput"><span class="keyword">class</span></code> types can be substituted for tuples
        in most places. That includes using a non-aggregate <code class="computeroutput"><span class="keyword">class</span></code>
        type as the attribute type of a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>.
      </p>
<p>
        However, while compatible tuples can be substituted for aggregates, you
        <span class="bold"><strong>can't</strong></span> substitute a tuple for some <code class="computeroutput"><span class="keyword">class</span></code> type <code class="computeroutput"><span class="identifier">T</span></code>
        just because the tuple could have been used to construct <code class="computeroutput"><span class="identifier">T</span></code>.
        Think of trying to invert the substitution in the second parse above. Converting
        a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span></code> into a <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span></code>
        makes no sense.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.alternative_parsers"></a><a class="link" href="tutorial.html#boost_parser.tutorial.alternative_parsers" title="Alternative Parsers">Alternative
      Parsers</a>
</h3></div></div></div>
<p>
        Frequently, you need to parse something that might have one of several forms.
        <code class="computeroutput"><span class="keyword">operator</span><span class="special">|</span></code>
        is overloaded to form alternative parsers. For example:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parser_1</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">eps</span><span class="special">;</span>
</pre>
<p>
        <code class="computeroutput"><span class="identifier">parser_1</span></code> matches an integer,
        or if that fails, it matches <span class="emphasis"><em>epsilon</em></span>, the empty string.
        This is equivalent to writing:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parser_2</span> <span class="special">=</span> <span class="special">-</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">;</span>
</pre>
<p>
        However, neither <code class="computeroutput"><span class="identifier">parser_1</span></code>
        nor <code class="computeroutput"><span class="identifier">parser_2</span></code> is equivalent
        to writing this:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parser_3</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">eps</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">;</span> <span class="comment">// Does not do what you think.</span>
</pre>
<p>
        The reason is that alternative parsers try each of their subparsers, one
        at a time, and stop on the first one that matches. <span class="emphasis"><em>Epsilon</em></span>
        matches anything, since it is zero length and consumes no input. It even
        matches the end of input. This means that <code class="computeroutput"><span class="identifier">parser_3</span></code>
        is equivalent to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
        by itself.
      </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          For this reason, writing <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a> <span class="special">|</span>
          <span class="identifier">p</span></code> for any parser p is considered
          a bug. Debug builds will assert when <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a> <span class="special">|</span>
          <span class="identifier">p</span></code> is encountered.
        </p></td></tr>
</table></div>
<div class="warning"><table border="0" summary="Warning">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../doc/src/images/warning.png"></td>
<th align="left">Warning</th>
</tr>
<tr><td align="left" valign="top"><p>
          This kind of error is very common when <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code> is involved, and also
          very easy to detect. However, it is possible to write <code class="computeroutput"><span class="identifier">P1</span>
          <span class="special">&gt;&gt;</span> <span class="identifier">P2</span></code>,
          where <code class="computeroutput"><span class="identifier">P1</span></code> is a prefix of
          <code class="computeroutput"><span class="identifier">P2</span></code>, such as <code class="computeroutput"><span class="identifier">int_</span> <span class="special">|</span> <span class="keyword">int</span> <span class="special">&gt;&gt;</span> <span class="identifier">int_</span></code>, or <code class="computeroutput"><span class="identifier">repeat</span><span class="special">(</span><span class="number">4</span><span class="special">)[</span><span class="identifier">hex_digit</span><span class="special">]</span>
          <span class="special">|</span> <span class="identifier">repeat</span><span class="special">(</span><span class="number">8</span><span class="special">)[</span><span class="identifier">hex_digit</span><span class="special">]</span></code>.
          This is almost certainly an error, but is impossible to detect in the general
          case — remember that <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code> can be separately compiled,
          and consider a pair of rules whose associated <code class="computeroutput"><span class="identifier">_def</span></code>
          parsers are <code class="computeroutput"><span class="identifier">int_</span></code> and <code class="computeroutput"><span class="identifier">int_</span> <span class="special">&gt;&gt;</span>
          <span class="identifier">int_</span></code>, respectively.
        </p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.parsing_quoted_strings"></a><a class="link" href="tutorial.html#boost_parser.tutorial.parsing_quoted_strings" title="Parsing Quoted Strings">Parsing
      Quoted Strings</a>
</h3></div></div></div>
<p>
        It is very common to need to parse quoted strings. Quoted strings are slightly
        tricky, though, when using a skipper (and you should be using a skipper 99%
        of the time). You don't want to allow arbitrary whitespace in the middle
        of your strings, and you also don't want to remove all whitespace from your
        strings. Both of these things will happen with the typical skipper, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a13a98612c59d598c30d400ff92c7765f.html" title="Global ws">ws</a></code>.
      </p>
<p>
        So, here is how most people would write a quoted string parser:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">string</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">&gt;</span> <span class="char">'"'</span><span class="special">];</span>
</pre>
<p>
        Some things to note:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            the result is a string;
          </li>
<li class="listitem">
            the quotes are not included in the result;
          </li>
<li class="listitem">
            there is an expectation point before the close-quote;
          </li>
<li class="listitem">
            the use of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc4518d7b420ac61d70ea3405ec74fd.html" title="Global lexeme">lexeme[]</a></code> disables skipping in the
            parser, and it must be written around the quotes, not around the <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code>
            expression; and
          </li>
<li class="listitem">
            there's no way to write a quote in the middle of the string.
          </li>
</ul></div>
<p>
        This is a very common pattern. I have written a quoted string parser like
        this dozens of times. The parser above is the quick-and-dirty version. A
        more robust version would be able to handle escaped quotes within the string,
        and then would immediately also need to support escaped escape characters.
      </p>
<p>
        Boost.Parser provides <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa2226d7c167c672d4c2c0720766be73b.html" title="Global quoted_string">quoted_string</a></code> to use in place
        of this very common pattern. It supports quote- and escaped-character-escaping,
        using backslash as the escape character.
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="keyword">auto</span> <span class="identifier">result1</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"\"some text\""</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">quoted_string</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">result1</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">result1</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span> <span class="comment">// Prints: some text</span>

<span class="keyword">auto</span> <span class="identifier">result2</span> <span class="special">=</span>
    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"\"some \\\"text\\\"\""</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">quoted_string</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">result2</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">result2</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span> <span class="comment">// Prints: some "text"</span>
</pre>
<p>
      </p>
<p>
        As common as this use case is, there are very similar use cases that it does
        not cover. So, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa2226d7c167c672d4c2c0720766be73b.html" title="Global quoted_string">quoted_string</a></code> has some options.
        If you call it with a single character, it returns a <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa2226d7c167c672d4c2c0720766be73b.html" title="Global quoted_string">quoted_string</a></code> that uses that
        single character as the quote-character.
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">result3</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"!some text!"</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">quoted_string</span><span class="special">(</span><span class="char">'!'</span><span class="special">),</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">result3</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">result3</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span> <span class="comment">// Prints: some text</span>
</pre>
<p>
      </p>
<p>
        You can also supply a range of characters. One of the characters from the
        range must quote both ends of the string; mismatches are not allowed. Think
        of how Python allows you to quote a string with either <code class="computeroutput"><span class="char">'"'</span></code>
        or <code class="computeroutput"><span class="char">'\''</span></code>, but the same character
        must be used on both sides.
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">result4</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"'some text'"</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">quoted_string</span><span class="special">(</span><span class="string">"'\""</span><span class="special">),</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">result4</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">result4</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span> <span class="comment">// Prints: some text</span>
</pre>
<p>
      </p>
<p>
        Another common thing to do in a quoted string parser is to recognize escape
        sequences. If you have simple escape sequencecs that do not require any real
        parsing, like say the simple escape sequences from C++, you can provide a
        <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code>
        object as well. The template parameter <code class="computeroutput"><span class="identifier">T</span></code>
        to <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols&lt;T&gt;</a></code>
        must be <code class="computeroutput"><span class="keyword">char</span></code> or <code class="computeroutput"><span class="keyword">char32_t</span></code>. You don't need to include the escaped
        backslash or the escaped quote character, since those always work.
      </p>
<p>
</p>
<pre class="programlisting"><span class="comment">// the c++ simple escapes</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">escapes</span> <span class="special">=</span> <span class="special">{</span>
    <span class="special">{</span><span class="string">"'"</span><span class="special">,</span> <span class="char">'\''</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"?"</span><span class="special">,</span> <span class="char">'\?'</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"a"</span><span class="special">,</span> <span class="char">'\a'</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"b"</span><span class="special">,</span> <span class="char">'\b'</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"f"</span><span class="special">,</span> <span class="char">'\f'</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"n"</span><span class="special">,</span> <span class="char">'\n'</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"r"</span><span class="special">,</span> <span class="char">'\r'</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"t"</span><span class="special">,</span> <span class="char">'\t'</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"v"</span><span class="special">,</span> <span class="char">'\v'</span><span class="special">}};</span>
<span class="keyword">auto</span> <span class="identifier">result5</span> <span class="special">=</span>
    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"\"some text\r\""</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">quoted_string</span><span class="special">(</span><span class="char">'"'</span><span class="special">,</span> <span class="identifier">escapes</span><span class="special">),</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">result5</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">result5</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span> <span class="comment">// Prints (with a CRLF newline): some text</span>
</pre>
<p>
      </p>
<p>
        Additionally, with each of the forms shown above, you can optionally provide
        a parser as a final argument, to will be used to parse each character inside
        the quotes. You have to provide an actual full parser here; you cannot provide
        a character or string literal. If you do not provide a character parser,
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>
        is used.
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">result6</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span>
    <span class="string">"'some text'"</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">quoted_string</span><span class="special">(</span><span class="string">"'\""</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'g'</span><span class="special">)),</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(!</span><span class="identifier">result6</span><span class="special">);</span>
<span class="identifier">result6</span> <span class="special">=</span>
    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"'gggg'"</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">quoted_string</span><span class="special">(</span><span class="string">"'\""</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'g'</span><span class="special">)),</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">result6</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">result6</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span> <span class="comment">// Prints: gggg</span>
</pre>
<p>
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.parsing_in_detail"></a><a class="link" href="tutorial.html#boost_parser.tutorial.parsing_in_detail" title="Parsing In Detail">Parsing In Detail</a>
</h3></div></div></div>
<p>
        Now that you've seen some examples, let's see how parsing works in a bit
        more detail. Consider this example.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">int_pair</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">;</span>         <span class="comment">// Attribute: tuple&lt;int, int&gt;</span>
<span class="keyword">auto</span> <span class="identifier">int_pairs_plus</span> <span class="special">=</span> <span class="special">+</span><span class="identifier">int_pair</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">;</span>  <span class="comment">// Attribute: tuple&lt;std::vector&lt;tuple&lt;int, int&gt;&gt;, int&gt;</span>
</pre>
<p>
        <code class="computeroutput"><span class="identifier">int_pairs_plus</span></code> must match
        a pair of <code class="computeroutput"><span class="keyword">int</span></code>s (using <code class="computeroutput"><span class="identifier">int_pair</span></code>) one or more times, and then must
        match an additional <code class="computeroutput"><span class="keyword">int</span></code>. In
        other words, it matches any odd number (greater than 1) of <code class="computeroutput"><span class="keyword">int</span></code>s in the input. Let's look at how this
        parse proceeds.
      </p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"1 2 3"</span><span class="special">,</span> <span class="identifier">int_pairs_plus</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
</pre>
<p>
        At the beginning of the parse, the top level parser uses its first subparser
        (if any) to start parsing. So, <code class="computeroutput"><span class="identifier">int_pairs_plus</span></code>,
        being a sequence parser, would pass control to its first parser <code class="computeroutput"><span class="special">+</span><span class="identifier">int_pair</span></code>.
        Then <code class="computeroutput"><span class="special">+</span><span class="identifier">int_pair</span></code>
        would use <code class="computeroutput"><span class="identifier">int_pair</span></code> to do
        its parsing, which would in turn use <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span></code>.
        This creates a stack of parsers, each one using a particular subparser.
      </p>
<p>
        Step 1) The input is <code class="computeroutput"><span class="string">"1 2 3"</span></code>,
        and the stack of active parsers is <code class="computeroutput"><span class="identifier">int_pairs_plus</span></code>
        -&gt; <code class="computeroutput"><span class="special">+</span><span class="identifier">int_pair</span></code>
        -&gt; <code class="computeroutput"><span class="identifier">int_pair</span></code> -&gt; <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span></code>.
        (Read "-&gt;" as "uses".) This parses <code class="computeroutput"><span class="string">"1"</span></code>,
        and the whitespace after is skipped by <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span></code>. Control
        passes to the second <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span></code> parser in <code class="computeroutput"><span class="identifier">int_pair</span></code>.
      </p>
<p>
        Step 2) The input is <code class="computeroutput"><span class="string">"2 3"</span></code>
        and the stack of parsers looks the same, except the active parser is the
        second <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span></code> from <code class="computeroutput"><span class="identifier">int_pair</span></code>.
        This parser consumes <code class="computeroutput"><span class="string">"2"</span></code>
        and then <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span></code> skips the subsequent space. Since we've
        finished with <code class="computeroutput"><span class="identifier">int_pair</span></code>'s
        match, its <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span>
        <span class="keyword">int</span><span class="special">&gt;</span></code>
        attribute is complete. It's parent is <code class="computeroutput"><span class="special">+</span><span class="identifier">int_pair</span></code>, so this tuple attribute is pushed
        onto the back of <code class="computeroutput"><span class="special">+</span><span class="identifier">int_pair</span></code>'s
        attribute, which is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;&gt;</span></code>. Control passes up to the parent
        of <code class="computeroutput"><span class="identifier">int_pair</span></code>, <code class="computeroutput"><span class="special">+</span><span class="identifier">int_pair</span></code>.
        Since <code class="computeroutput"><span class="special">+</span><span class="identifier">int_pair</span></code>
        is a one-or-more parser, it starts a new iteration; control passes to <code class="computeroutput"><span class="identifier">int_pair</span></code> again.
      </p>
<p>
        Step 3) The input is <code class="computeroutput"><span class="string">"3"</span></code>
        and the stack of parsers looks the same, except the active parser is the
        first <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span></code> from <code class="computeroutput"><span class="identifier">int_pair</span></code>
        again, and we're in the second iteration of <code class="computeroutput"><span class="special">+</span><span class="identifier">int_pair</span></code>. This parser consumes <code class="computeroutput"><span class="string">"3"</span></code>. Since this is the end of the
        input, the second <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span></code> of <code class="computeroutput"><span class="identifier">int_pair</span></code>
        does not match. This partial match of <code class="computeroutput"><span class="string">"3"</span></code>
        should not count, since it was not part of a full match. So, <code class="computeroutput"><span class="identifier">int_pair</span></code> indicates its failure, and <code class="computeroutput"><span class="special">+</span><span class="identifier">int_pair</span></code>
        stops iterating. Since it did match once, <code class="computeroutput"><span class="special">+</span><span class="identifier">int_pair</span></code> does not fail; it is a zero-or-more
        parser; failure of its subparser after the first success does not cause it
        to fail. Control passes to the next parser in sequence within <code class="computeroutput"><span class="identifier">int_pairs_plus</span></code>.
      </p>
<p>
        Step 4) The input is <code class="computeroutput"><span class="string">"3"</span></code>
        again, and the stack of parsers is <code class="computeroutput"><span class="identifier">int_pairs_plus</span></code>
        -&gt; <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span></code>. This parses the <code class="computeroutput"><span class="string">"3"</span></code>,
        and the parse reaches the end of input. Control passes to <code class="computeroutput"><span class="identifier">int_pairs_plus</span></code>,
        which has just successfully matched with all parser in its sequence. It then
        produces its attribute, a <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;&gt;,</span> <span class="keyword">int</span><span class="special">&gt;</span></code>, which gets returned from <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">()</span></code>.
      </p>
<p>
        Something to take note of between Steps #3 and #4: at the beginning of #4,
        the input position had returned to where is was at the beginning of #3. This
        kind of backtracking happens in alternative parsers when an alternative fails.
        The next page has more details on the semantics of backtracking.
      </p>
<h5>
<a name="boost_parser.tutorial.parsing_in_detail.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.parsing_in_detail.parsers_in_detail"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.parsing_in_detail.parsers_in_detail">Parsers
        in detail</a>
      </h5>
<p>
        So far, parsers have been presented as somewhat abstract entities. You may
        be wanting more detail. A Boost.Parser parser <code class="computeroutput"><span class="identifier">P</span></code>
        is an invocable object with a pair of call operator overloads. The two functions
        are very similar, and in many parsers one is implemented in terms of the
        other. The first function does the parsing and returns the default attribute
        for the parser. The second function does exactly the same parsing, but takes
        an out-param into which it writes the attribute for the parser. The out-param
        does not need to be the same type as the default attribute, but they need
        to be compatible.
      </p>
<p>
        Compatibility means that the default attribute is assignable to the out-param
        in some fashion. This usually means direct assignment, but it may also mean
        a tuple -&gt; aggregate or aggregate -&gt; tuple conversion. For sequence
        types, compatibility means that the sequence type has <code class="computeroutput"><span class="identifier">insert</span></code>
        or <code class="computeroutput"><span class="identifier">push_back</span></code> with the usual
        semantics. This means that the parser <code class="computeroutput"><span class="special">+</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">int_</span></code> can fill a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">set</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code> just
        as well as a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code>.
      </p>
<p>
        Some parsers also have additional state that is required to perform a match.
        For instance, <code class="computeroutput"><span class="identifier">char_</span></code> parsers
        can be parameterized with a single code point to match; the exact value of
        that code point is stored in the parser object.
      </p>
<p>
        No parser has direct support for all the operations defined on parsers (<code class="computeroutput"><span class="keyword">operator</span><span class="special">|</span></code>,
        <code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;&gt;</span></code>,
        etc.). Instead, there is a template called <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1parser__interface.html" title="Struct template parser_interface">parser_interface</a></code> that supports
        all of these operations. <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1parser__interface.html" title="Struct template parser_interface">parser_interface</a></code> wraps each
        parser, storing it as a data member, adapting it for general use. You should
        only ever see <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1parser__interface.html" title="Struct template parser_interface">parser_interface</a></code> in the debugger,
        or possibly in some of the reference documentation. You should never have
        to write it in your own code.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.backtracking"></a><a class="link" href="tutorial.html#boost_parser.tutorial.backtracking" title="Backtracking">Backtracking</a>
</h3></div></div></div>
<p>
        As described in the previous page, backtracking occurs when the parse attempts
        to match the current parser <code class="computeroutput"><span class="identifier">P</span></code>,
        matches part of the input, but fails to match all of <code class="computeroutput"><span class="identifier">P</span></code>.
        The part of the input consumed during the parse of <code class="computeroutput"><span class="identifier">P</span></code>
        is essentially "given back".
      </p>
<p>
        This is necessary because <code class="computeroutput"><span class="identifier">P</span></code>
        may consist of subparsers, and each subparser that succeeds will try to consume
        input, produce attributes, etc. When a later subparser fails, the parse of
        <code class="computeroutput"><span class="identifier">P</span></code> fails, and the input must
        be rewound to where it was when <code class="computeroutput"><span class="identifier">P</span></code>
        started its parse, not where the latest matching subparser stopped.
      </p>
<p>
        Alternative parsers will often evaluate multiple subparsers one at a time,
        advancing and then restoring the input position, until one of the subparsers
        succeeds. Consider this example.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="identifier">repeat</span><span class="special">(</span><span class="number">53</span><span class="special">)[</span><span class="identifier">other_parser</span><span class="special">]</span> <span class="special">|</span> <span class="identifier">repeat</span><span class="special">(</span><span class="number">10</span><span class="special">)[</span><span class="identifier">other_parser</span><span class="special">];</span>
</pre>
<p>
        Evaluating <code class="computeroutput"><span class="identifier">parser</span></code> means trying
        to match <code class="computeroutput"><span class="identifier">other_parser</span></code> 53
        times, and if that fails, trying to match <code class="computeroutput"><span class="identifier">other_parser</span></code>
        10 times. Say you parse input that matches <code class="computeroutput"><span class="identifier">other_parser</span></code>
        11 times. <code class="computeroutput"><span class="identifier">parser</span></code> will match
        it. It will also evaluate <code class="computeroutput"><span class="identifier">other_parser</span></code>
        21 times during the parse.
      </p>
<p>
        The attributes of the <code class="computeroutput"><span class="identifier">repeat</span><span class="special">(</span><span class="number">53</span><span class="special">)[</span><span class="identifier">other_parser</span><span class="special">]</span></code>
        and <code class="computeroutput"><span class="identifier">repeat</span><span class="special">(</span><span class="number">10</span><span class="special">)[</span><span class="identifier">other_parser</span><span class="special">]</span></code> are each <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">other_parser</span><span class="special">)&gt;</span></code>; let's say that <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">other_parser</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">int</span></code>.
        The attribute of <code class="computeroutput"><span class="identifier">parser</span></code> as
        a whole is the same, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code>.
        Since <code class="computeroutput"><span class="identifier">other_parser</span></code> is busy
        producing <code class="computeroutput"><span class="keyword">int</span></code>s — 21 of
        them to be exact — you may be wondering what happens to the ones produced
        during the evaluation of <code class="computeroutput"><span class="identifier">repeat</span><span class="special">(</span><span class="number">53</span><span class="special">)[</span><span class="identifier">other_parser</span><span class="special">]</span></code>
        when it fails to find all 53 inputs. Its <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code>
        will contain 11 <code class="computeroutput"><span class="keyword">int</span></code>s at that
        point.
      </p>
<p>
        When a repeat-parser fails, and attributes are being generated, it clears
        its container. This applies to parsers such as the ones above, but also all
        the other repeat parsers, including ones made using <code class="computeroutput"><span class="keyword">operator</span><span class="special">+</span></code> or <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code>.
      </p>
<p>
        So, at the end of a successful parse by <code class="computeroutput"><span class="identifier">parser</span></code>
        of 10 inputs (since the right side of the alternative only eats 10 repetitions),
        the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code> attribute
        of <code class="computeroutput"><span class="identifier">parser</span></code> would contain 10
        <code class="computeroutput"><span class="keyword">int</span></code>s.
      </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          Users of Boost.Spirit may be familiar with the <code class="computeroutput"><span class="identifier">hold</span><span class="special">[]</span></code> directive. Because of the behavior described
          above, there is no such directive in Boost.Parser.
        </p></td></tr>
</table></div>
<h5>
<a name="boost_parser.tutorial.backtracking.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.backtracking.expectation_points"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.backtracking.expectation_points">Expectation
        points</a>
      </h5>
<p>
        Ok, so if parsers all try their best to match the input, and are all-or-nothing,
        doesn't that leave room for all kinds of bad input to be ignored? Consider
        the top-level parser from the <a class="link" href="extended_examples.html#boost_parser.extended_examples.parsing_json" title="Parsing JSON">Parsing
        JSON</a> example.
      </p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">value_p_def</span> <span class="special">=</span>
    <span class="identifier">number</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">bool_</span> <span class="special">|</span> <span class="identifier">null</span> <span class="special">|</span> <span class="identifier">string</span> <span class="special">|</span> <span class="identifier">array_p</span> <span class="special">|</span> <span class="identifier">object_p</span><span class="special">;</span>
</pre>
<p>
        What happens if I use this to parse <code class="computeroutput"><span class="string">"\""</span></code>?
        The parse tries <code class="computeroutput"><span class="identifier">number</span></code>, fails.
        It then tries <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">bool_</span></code>, fails. Then <code class="computeroutput"><span class="identifier">null</span></code>
        fails too. Finally, it starts parsing <code class="computeroutput"><span class="identifier">string</span></code>.
        Good news, the first character is the open-quote of a JSON string. Unfortunately,
        that's also the end of the input, so <code class="computeroutput"><span class="identifier">string</span></code>
        must fail too. However, we probably don't want to just give up on parsing
        <code class="computeroutput"><span class="identifier">string</span></code> now and try <code class="computeroutput"><span class="identifier">array_p</span></code>, right? If the user wrote an open-quote
        with no matching close-quote, that's not the prefix of some later alternative
        of <code class="computeroutput"><span class="identifier">value_p_def</span></code>; it's ill-formed
        JSON. Here's the parser for the <code class="computeroutput"><span class="identifier">string</span></code>
        rule:
      </p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">string_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="identifier">string_char</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">&gt;</span> <span class="char">'"'</span><span class="special">];</span>
</pre>
<p>
        Notice that <code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;</span></code>
        is used on the right instead of <code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;&gt;</span></code>. This indicates the same sequence
        operation as <code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;&gt;</span></code>,
        except that it also represents an expectation. If the parse before the <code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;</span></code>
        succeeds, whatever comes after it <span class="bold"><strong>must</strong></span> also
        succeed. Otherwise, the top-level parse is failed, and a diagnostic is emitted.
        It will say something like "Expected '"' here.", quoting the
        line, with a caret pointing to the place in the input where it expected the
        right-side match.
      </p>
<p>
        Choosing to use <code class="computeroutput"><span class="special">&gt;</span></code> versus
        <code class="computeroutput"><span class="special">&gt;&gt;</span></code> is how you indicate
        to Boost.Parser that parse failure is or is not a hard error, respectively.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.symbol_tables"></a><a class="link" href="tutorial.html#boost_parser.tutorial.symbol_tables" title="Symbol Tables">Symbol Tables</a>
</h3></div></div></div>
<p>
        When writing a parser, it often comes up that there is a set of strings that,
        when parsed, are associated with a set of values one-to-one. It is tedious
        to write parsers that recognize all the possible input strings when you have
        to associate each one with an attribute via a semantic action. Instead, we
        can use a symbol table.
      </p>
<p>
        Say we want to parse Roman numerals, one of the most common work-related
        parsing problems. We want to recognize numbers that start with any number
        of "M"s, representing thousands, followed by the hundreds, the
        tens, and the ones. Any of these may be absent from the input, but not all.
        Here are three symbol Boost.Parser tables that we can use to recognize ones,
        tens, and hundreds values, respectively:
      </p>
<p>
</p>
<pre class="programlisting"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">ones</span> <span class="special">=</span> <span class="special">{</span>
    <span class="special">{</span><span class="string">"I"</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"II"</span><span class="special">,</span> <span class="number">2</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"III"</span><span class="special">,</span> <span class="number">3</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"IV"</span><span class="special">,</span> <span class="number">4</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"V"</span><span class="special">,</span> <span class="number">5</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"VI"</span><span class="special">,</span> <span class="number">6</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"VII"</span><span class="special">,</span> <span class="number">7</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"VIII"</span><span class="special">,</span> <span class="number">8</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"IX"</span><span class="special">,</span> <span class="number">9</span><span class="special">}};</span>

<span class="identifier">bp</span><span class="special">::</span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">tens</span> <span class="special">=</span> <span class="special">{</span>
    <span class="special">{</span><span class="string">"X"</span><span class="special">,</span> <span class="number">10</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"XX"</span><span class="special">,</span> <span class="number">20</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"XXX"</span><span class="special">,</span> <span class="number">30</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"XL"</span><span class="special">,</span> <span class="number">40</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"L"</span><span class="special">,</span> <span class="number">50</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"LX"</span><span class="special">,</span> <span class="number">60</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"LXX"</span><span class="special">,</span> <span class="number">70</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"LXXX"</span><span class="special">,</span> <span class="number">80</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"XC"</span><span class="special">,</span> <span class="number">90</span><span class="special">}};</span>

<span class="identifier">bp</span><span class="special">::</span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">hundreds</span> <span class="special">=</span> <span class="special">{</span>
    <span class="special">{</span><span class="string">"C"</span><span class="special">,</span> <span class="number">100</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"CC"</span><span class="special">,</span> <span class="number">200</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"CCC"</span><span class="special">,</span> <span class="number">300</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"CD"</span><span class="special">,</span> <span class="number">400</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"D"</span><span class="special">,</span> <span class="number">500</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"DC"</span><span class="special">,</span> <span class="number">600</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"DCC"</span><span class="special">,</span> <span class="number">700</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"DCCC"</span><span class="special">,</span> <span class="number">800</span><span class="special">},</span>
    <span class="special">{</span><span class="string">"CM"</span><span class="special">,</span> <span class="number">900</span><span class="special">}};</span>
</pre>
<p>
      </p>
<p>
        A <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code>
        maps strings of <code class="computeroutput"><span class="keyword">char</span></code> to their
        associated attributes. The type of the attribute must be specified as a template
        parameter to <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code>
        — in this case, <code class="computeroutput"><span class="keyword">int</span></code>.
      </p>
<p>
        Any "M"s we encounter should add 1000 to the result, and all other
        values come from the symbol tables. Here are the semantic actions we'll need
        to do that:
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">result</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">add_1000</span> <span class="special">=</span> <span class="special">[&amp;</span><span class="identifier">result</span><span class="special">](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">result</span> <span class="special">+=</span> <span class="number">1000</span><span class="special">;</span> <span class="special">};</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">add</span> <span class="special">=</span> <span class="special">[&amp;</span><span class="identifier">result</span><span class="special">](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">result</span> <span class="special">+=</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">);</span> <span class="special">};</span>
</pre>
<p>
      </p>
<p>
        <code class="computeroutput"><span class="identifier">add_1000</span></code> just adds <code class="computeroutput"><span class="number">1000</span></code> to <code class="computeroutput"><span class="identifier">result</span></code>.
        <code class="computeroutput"><span class="identifier">add</span></code> adds whatever attribute
        is produced by its parser to <code class="computeroutput"><span class="identifier">result</span></code>.
      </p>
<p>
        Now we just need to put the pieces together to make a parser:
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parser</span> <span class="special">=</span>
    <span class="special">*</span><span class="char">'M'</span><span class="identifier">_l</span><span class="special">[</span><span class="identifier">add_1000</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="special">-</span><span class="identifier">hundreds</span><span class="special">[</span><span class="identifier">add</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="special">-</span><span class="identifier">tens</span><span class="special">[</span><span class="identifier">add</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="special">-</span><span class="identifier">ones</span><span class="special">[</span><span class="identifier">add</span><span class="special">];</span>
</pre>
<p>
      </p>
<p>
        We've got a few new bits in play here, so let's break it down. <code class="computeroutput"><span class="char">'M'</span><span class="identifier">_l</span></code> is a
        <span class="emphasis"><em>literal parser</em></span>. That is, it is a parser that parses
        a literal <code class="computeroutput"><span class="keyword">char</span></code>, code point,
        or string. In this case, a <code class="computeroutput"><span class="keyword">char</span></code>
        <code class="computeroutput"><span class="char">'M'</span></code> is being parsed. The <code class="computeroutput"><span class="identifier">_l</span></code> bit at the end is a <a href="https://en.cppreference.com/w/cpp/language/user_literal" target="_top">UDL</a>
        suffix that you can put after any <code class="computeroutput"><span class="keyword">char</span></code>,
        <code class="computeroutput"><span class="keyword">char32_t</span></code>, or <code class="computeroutput"><span class="keyword">char</span>
        <span class="keyword">const</span> <span class="special">*</span></code>
        to form a literal parser. You can also make a literal parser by writing
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa8c123b0cbde389f5d5eaf353169ef09.html" title="Function lit">lit()</a></code>, passing an argument of
        one of the previously mentioned types.
      </p>
<p>
        Why do we need any of this, considering that we just used a literal <code class="computeroutput"><span class="char">','</span></code> in our previous example? The reason is that
        <code class="computeroutput"><span class="char">'M'</span></code> is not used in an expression
        with another Boost.Parser parser. It is used within <code class="computeroutput"><span class="special">*</span><span class="char">'M'</span><span class="identifier">_l</span><span class="special">[</span><span class="identifier">add_1000</span><span class="special">]</span></code>.
        If we'd written <code class="computeroutput"><span class="special">*</span><span class="char">'M'</span><span class="special">[</span><span class="identifier">add_1000</span><span class="special">]</span></code>, clearly that would be ill-formed; <code class="computeroutput"><span class="keyword">char</span></code> has no <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code>, nor an <code class="computeroutput"><span class="keyword">operator</span><span class="special">[]</span></code>, associated with it.
      </p>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
          Any time you want to use a <code class="computeroutput"><span class="keyword">char</span></code>,
          <code class="computeroutput"><span class="keyword">char32_t</span></code>, or string literal
          in a Boost.Parser parser, write it as-is if it is combined with a preexisting
          Boost.Parser subparser <code class="computeroutput"><span class="identifier">p</span></code>,
          as in <code class="computeroutput"><span class="char">'x'</span> <span class="special">&gt;&gt;</span>
          <span class="identifier">p</span></code>. Otherwise, you need to wrap
          it in a call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa8c123b0cbde389f5d5eaf353169ef09.html" title="Function lit">lit()</a></code>, or use the <code class="computeroutput"><span class="identifier">_l</span></code> <a href="https://en.cppreference.com/w/cpp/language/user_literal" target="_top">UDL</a>
          suffix.
        </p></td></tr>
</table></div>
<p>
        On to the next bit: <code class="computeroutput"><span class="special">-</span><span class="identifier">hundreds</span><span class="special">[</span><span class="identifier">add</span><span class="special">]</span></code>.
        By now, the use of the index operator should be pretty familiar; it associates
        the semantic action <code class="computeroutput"><span class="identifier">add</span></code> with
        the parser <code class="computeroutput"><span class="identifier">hundreds</span></code>. The
        <code class="computeroutput"><span class="keyword">operator</span><span class="special">-</span></code>
        at the beginning is new. It means that the parser it is applied to is optional.
        You can read it as "zero or one". So, if <code class="computeroutput"><span class="identifier">hundreds</span></code>
        is not successfully parsed after <code class="computeroutput"><span class="special">*</span><span class="char">'M'</span><span class="special">[</span><span class="identifier">add_1000</span><span class="special">]</span></code>, nothing happens, because <code class="computeroutput"><span class="identifier">hundreds</span></code> is allowed to be missing —
        it's optional. If <code class="computeroutput"><span class="identifier">hundreds</span></code>
        is parsed successfully, say by matching <code class="computeroutput"><span class="string">"CC"</span></code>,
        the resulting attribute, <code class="computeroutput"><span class="number">200</span></code>,
        is added to <code class="computeroutput"><span class="identifier">result</span></code> inside
        <code class="computeroutput"><span class="identifier">add</span></code>.
      </p>
<p>
        Here is the full listing of the program. Notice that it would have been inappropriate
        to use a whitespace skipper here, since the entire parse is a single number,
        so it was removed.
      </p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">parser</span><span class="special">/</span><span class="identifier">parser</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>


<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Enter a number using Roman numerals. "</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">input</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">,</span> <span class="identifier">input</span><span class="special">);</span>

    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">ones</span> <span class="special">=</span> <span class="special">{</span>
        <span class="special">{</span><span class="string">"I"</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"II"</span><span class="special">,</span> <span class="number">2</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"III"</span><span class="special">,</span> <span class="number">3</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"IV"</span><span class="special">,</span> <span class="number">4</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"V"</span><span class="special">,</span> <span class="number">5</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"VI"</span><span class="special">,</span> <span class="number">6</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"VII"</span><span class="special">,</span> <span class="number">7</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"VIII"</span><span class="special">,</span> <span class="number">8</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"IX"</span><span class="special">,</span> <span class="number">9</span><span class="special">}};</span>

    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">tens</span> <span class="special">=</span> <span class="special">{</span>
        <span class="special">{</span><span class="string">"X"</span><span class="special">,</span> <span class="number">10</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"XX"</span><span class="special">,</span> <span class="number">20</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"XXX"</span><span class="special">,</span> <span class="number">30</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"XL"</span><span class="special">,</span> <span class="number">40</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"L"</span><span class="special">,</span> <span class="number">50</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"LX"</span><span class="special">,</span> <span class="number">60</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"LXX"</span><span class="special">,</span> <span class="number">70</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"LXXX"</span><span class="special">,</span> <span class="number">80</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"XC"</span><span class="special">,</span> <span class="number">90</span><span class="special">}};</span>

    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">hundreds</span> <span class="special">=</span> <span class="special">{</span>
        <span class="special">{</span><span class="string">"C"</span><span class="special">,</span> <span class="number">100</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"CC"</span><span class="special">,</span> <span class="number">200</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"CCC"</span><span class="special">,</span> <span class="number">300</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"CD"</span><span class="special">,</span> <span class="number">400</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"D"</span><span class="special">,</span> <span class="number">500</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"DC"</span><span class="special">,</span> <span class="number">600</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"DCC"</span><span class="special">,</span> <span class="number">700</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"DCCC"</span><span class="special">,</span> <span class="number">800</span><span class="special">},</span>
        <span class="special">{</span><span class="string">"CM"</span><span class="special">,</span> <span class="number">900</span><span class="special">}};</span>

    <span class="keyword">int</span> <span class="identifier">result</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">add_1000</span> <span class="special">=</span> <span class="special">[&amp;</span><span class="identifier">result</span><span class="special">](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">result</span> <span class="special">+=</span> <span class="number">1000</span><span class="special">;</span> <span class="special">};</span>
    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">add</span> <span class="special">=</span> <span class="special">[&amp;</span><span class="identifier">result</span><span class="special">](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">result</span> <span class="special">+=</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">);</span> <span class="special">};</span>

    <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parser</span> <span class="special">=</span>
        <span class="special">*</span><span class="char">'M'</span><span class="identifier">_l</span><span class="special">[</span><span class="identifier">add_1000</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="special">-</span><span class="identifier">hundreds</span><span class="special">[</span><span class="identifier">add</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="special">-</span><span class="identifier">tens</span><span class="special">[</span><span class="identifier">add</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="special">-</span><span class="identifier">ones</span><span class="special">[</span><span class="identifier">add</span><span class="special">];</span>

    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">parser</span><span class="special">)</span> <span class="special">&amp;&amp;</span> <span class="identifier">result</span> <span class="special">!=</span> <span class="number">0</span><span class="special">)</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"That's "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span> <span class="special">&lt;&lt;</span> <span class="string">" in Arabic numerals.\n"</span><span class="special">;</span>
    <span class="keyword">else</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"That's not a Roman number.\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code>
          stores all its strings in UTF-32 internally. If you do Unicode or ASCII
          parsing, this will not matter to you at all. If you do non-Unicode parsing
          of a character encoding that is not a subset of Unicode (EBCDIC, for instance),
          it could cause problems. See the section on <a class="link" href="tutorial.html#boost_parser.tutorial.unicode_support" title="Unicode Support">Unicode
          Support</a> for more information.
        </p></td></tr>
</table></div>
<h5>
<a name="boost_parser.tutorial.symbol_tables.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.symbol_tables.diagnostic_messages"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.symbol_tables.diagnostic_messages">Diagnostic
        messages</a>
      </h5>
<p>
        Just like with a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>,
        you can give a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code>
        a bit of diagnostic text that will be used in error messages generated by
        Boost.Parser when the parse fails at an expectation point, as described in
        <a class="link" href="tutorial.html#boost_parser.tutorial.error_handling_and_debugging" title="Error Handling and Debugging">Error
        Handling and Debugging</a>. See the <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code> constructors for details.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.mutable_symbol_tables"></a><a class="link" href="tutorial.html#boost_parser.tutorial.mutable_symbol_tables" title="Mutable Symbol Tables">Mutable
      Symbol Tables</a>
</h3></div></div></div>
<p>
        The previous example showed how to use a symbol table as a fixed lookup table.
        What if we want to add things to the table during the parse? We can do that,
        but we need to do so within a semantic action. First, here is our symbol
        table, already with a single value in it:
      </p>
<p>
</p>
<pre class="programlisting"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">symbols</span> <span class="special">=</span> <span class="special">{{</span><span class="string">"c"</span><span class="special">,</span> <span class="number">8</span><span class="special">}};</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"c"</span><span class="special">,</span> <span class="identifier">symbols</span><span class="special">));</span>
</pre>
<p>
      </p>
<p>
        No surprise that it works to use the symbol table as a parser to parse the
        one string in the symbol table. Now, here's our parser:
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">)[</span><span class="identifier">add_symbol</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="identifier">symbols</span><span class="special">;</span>
</pre>
<p>
      </p>
<p>
        Here, we've attached the semantic action not to a simple parser like <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6e37283853b49605ec05b4a1969eaaac.html" title="Global double_">double_</a></code>,
        but to the sequence parser <code class="computeroutput"><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span>
        <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">)</span></code>. This sequence parser contains two parsers,
        each with its own attribute, so it produces two attributes as a tuple.
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">add_symbol</span> <span class="special">=</span> <span class="special">[&amp;</span><span class="identifier">symbols</span><span class="special">](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span>
    <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
    <span class="comment">// symbols::insert() requires a string, not a single character.</span>
    <span class="keyword">char</span> <span class="identifier">chars</span><span class="special">[</span><span class="number">2</span><span class="special">]</span> <span class="special">=</span> <span class="special">{</span><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)[</span><span class="number">0</span><span class="identifier">_c</span><span class="special">],</span> <span class="number">0</span><span class="special">};</span>
    <span class="identifier">symbols</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">chars</span><span class="special">,</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)[</span><span class="number">1</span><span class="identifier">_c</span><span class="special">]);</span>
<span class="special">};</span>
</pre>
<p>
      </p>
<p>
        Inside the semantic action, we can get the first element of the attribute
        tuple using <a href="https://en.cppreference.com/w/cpp/language/user_literal" target="_top">UDLs</a>
        provided by Boost.Hana, and <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">::</span><span class="keyword">operator</span><span class="special">[]()</span></code>. The first attribute, from the <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>,
        is <code class="computeroutput"><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)[</span><span class="number">0</span><span class="identifier">_c</span><span class="special">]</span></code>, and
        the second, from the <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aebfca0484fcebac2789c946c6a93b116.html" title="Global int_">int_</a></code>, is <code class="computeroutput"><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)[</span><span class="number">1</span><span class="identifier">_c</span><span class="special">]</span></code>
        (if <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a></code>
        aliases to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span></code>, you'd use <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span></code> or
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1af2e6576c852ac796a5bdea3c8ed321b8.html" title="Function template get">boost::parser::get</a></code>
        instead). To add the symbol to the symbol table, we call <code class="computeroutput"><span class="identifier">insert</span><span class="special">()</span></code>.
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">)[</span><span class="identifier">add_symbol</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="identifier">symbols</span><span class="special">;</span>
</pre>
<p>
      </p>
<p>
        During the parse, <code class="computeroutput"><span class="special">(</span><span class="string">"X"</span><span class="special">,</span> <span class="number">9</span><span class="special">)</span></code>
        is parsed and added to the symbol table. Then, the second <code class="computeroutput"><span class="char">'X'</span></code>
        is recognized by the symbol table parser. However:
      </p>
<p>
</p>
<pre class="programlisting"><span class="identifier">assert</span><span class="special">(!</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"X"</span><span class="special">,</span> <span class="identifier">symbols</span><span class="special">));</span>
</pre>
<p>
      </p>
<p>
        If we parse again, we find that <code class="computeroutput"><span class="string">"X"</span></code>
        did not stay in the symbol table. The fact that <code class="computeroutput"><span class="identifier">symbols</span></code>
        was declared const might have given you a hint that this would happen.
      </p>
<p>
        The full program:
      </p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">parser</span><span class="special">/</span><span class="identifier">parser</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span>


<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">symbols</span> <span class="special">=</span> <span class="special">{{</span><span class="string">"c"</span><span class="special">,</span> <span class="number">8</span><span class="special">}};</span>
    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"c"</span><span class="special">,</span> <span class="identifier">symbols</span><span class="special">));</span>

    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">add_symbol</span> <span class="special">=</span> <span class="special">[&amp;</span><span class="identifier">symbols</span><span class="special">](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span>
        <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
        <span class="comment">// symbols::insert() requires a string, not a single character.</span>
        <span class="keyword">char</span> <span class="identifier">chars</span><span class="special">[</span><span class="number">2</span><span class="special">]</span> <span class="special">=</span> <span class="special">{</span><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)[</span><span class="number">0</span><span class="identifier">_c</span><span class="special">],</span> <span class="number">0</span><span class="special">};</span>
        <span class="identifier">symbols</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">chars</span><span class="special">,</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)[</span><span class="number">1</span><span class="identifier">_c</span><span class="special">]);</span>
    <span class="special">};</span>
    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">)[</span><span class="identifier">add_symbol</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="identifier">symbols</span><span class="special">;</span>

    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">parse</span><span class="special">(</span><span class="string">"X 9 X"</span><span class="special">,</span> <span class="identifier">parser</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">result</span> <span class="special">&amp;&amp;</span> <span class="special">*</span><span class="identifier">result</span> <span class="special">==</span> <span class="number">9</span><span class="special">);</span>
    <span class="special">(</span><span class="keyword">void</span><span class="special">)</span><span class="identifier">result</span><span class="special">;</span>

    <span class="identifier">assert</span><span class="special">(!</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"X"</span><span class="special">,</span> <span class="identifier">symbols</span><span class="special">));</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code>
          stores all its strings in UTF-32 internally. If you do Unicode or ASCII
          parsing, this will not matter to you at all. If you do non-Unicode parsing
          of a character encoding that is not a subset of Unicode (EBCDIC, for instance),
          it could cause problems. See the section on <a class="link" href="tutorial.html#boost_parser.tutorial.unicode_support" title="Unicode Support">Unicode
          Support</a> for more information.
        </p></td></tr>
</table></div>
<p>
        It is possible to add symbols to a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code> permanently. To do
        so, you have to use a mutable <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code> object <code class="computeroutput"><span class="identifier">s</span></code>, and add the symbols by calling <code class="computeroutput"><span class="identifier">s</span><span class="special">.</span><span class="identifier">insert_for_next_parse</span><span class="special">()</span></code>, instead of <code class="computeroutput"><span class="identifier">s</span><span class="special">.</span><span class="identifier">insert</span><span class="special">()</span></code>. These two operations are orthogonal, so
        if you want to both add a symbol to the table for the current top-level parse,
        and leave it in the table for subsequent top-level parses, you need to call
        both functions.
      </p>
<p>
        It is also possible to erase a single entry from the symbol table, or to
        clear the symbol table entirely. Just as with insertion, there are versions
        of erase and clear for the current parse, and another that applies only to
        subsequent parses. The full set of operations can be found in the <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code>
        API docs.
      </p>
<p>
        [mpte There are two versions of each of the <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code> <code class="computeroutput"><span class="special">*</span><span class="identifier">_for_next_parse</span><span class="special">()</span></code>
        functions — one that takes a context, and one that does not. The one
        with the context is meant to be used within a semantic action. The one without
        the context is for use outside of any parse.]
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.the_parsers_and_their_uses"></a><a class="link" href="tutorial.html#boost_parser.tutorial.the_parsers_and_their_uses" title="The Parsers And Their Uses">The
      Parsers And Their Uses</a>
</h3></div></div></div>
<p>
        Boost.Parser comes with all the parsers most parsing tasks will ever need.
        Each one is a <code class="computeroutput"><span class="keyword">constexpr</span></code> object,
        or a <code class="computeroutput"><span class="keyword">constexpr</span></code> function. Some
        of the non-functions are also callable, such as <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>, which may be used directly,
        or with arguments, as in <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code><code class="computeroutput"><span class="special">(</span><span class="char">'a'</span><span class="special">,</span> <span class="char">'z'</span><span class="special">)</span></code>. Any parser that can be called, whether
        a function or callable object, will be called a <span class="emphasis"><em>callable parser</em></span>
        from now on. Note that there are no nullary callable parsers; they each take
        one or more arguments.
      </p>
<p>
        Each callable parser takes one or more <span class="emphasis"><em>parse arguments</em></span>.
        A parse argument may be a value or an invocable object that accepts a reference
        to the parse context. The reference parameter may be mutable or constant.
        For example:
      </p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">get_attribute</span>
<span class="special">{</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">&gt;</span>
    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Context</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="keyword">return</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">);</span>
    <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
        This can also be a lambda. For example:
      </p>
<pre class="programlisting"><span class="special">[](</span><span class="keyword">auto</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">);</span> <span class="special">}</span>
</pre>
<p>
        The operation that produces a value from a parse argument, which may be a
        value or a callable taking a parse context argument, is referred to as <span class="emphasis"><em>resolving</em></span>
        the parse argument. If a parse argument <code class="computeroutput"><span class="identifier">arg</span></code>
        can be called with the current context, then the resolved value of <code class="computeroutput"><span class="identifier">arg</span></code> is <code class="computeroutput"><span class="identifier">arg</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>;
        otherwise, the resolved value is just <code class="computeroutput"><span class="identifier">arg</span></code>.
      </p>
<p>
        Some callable parsers take a <span class="emphasis"><em>parse predicate</em></span>. A parse
        predicate is not quite the same as a parse argument, because it must be a
        callable object, and cannot be a value. A parse predicate's return type must
        be contextually convertible to <code class="computeroutput"><span class="keyword">bool</span></code>.
        For example:
      </p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">equals_three</span>
<span class="special">{</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">&gt;</span>
    <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Context</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="keyword">return</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
        This may of course be a lambda:
      </p>
<pre class="programlisting"><span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">;</span> <span class="special">}</span>
</pre>
<p>
        The notional macro <span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><code class="computeroutput"><span class="special">()</span></code> expands to the result of resolving a parse
        argument or parse predicate. You'll see it used in the rest of the documentation.
      </p>
<p>
        An example of how parse arguments are used:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="comment">// This parser matches one code point that is at least 'a', and at most</span>
<span class="comment">// the value of last_char, which comes from the globals.</span>
<span class="keyword">auto</span> <span class="identifier">last_char</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">_globals</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">).</span><span class="identifier">last_char</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">auto</span> <span class="identifier">subparser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">,</span> <span class="identifier">last_char</span><span class="special">);</span>
</pre>
<p>
        Don't worry for now about what the globals are for now; the take-away is
        that you can make any argument you pass to a parser depend on the current
        state of the parse, by using the parse context:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="comment">// This parser parses two code points.  For the parse to succeed, the</span>
<span class="comment">// second one must be &gt;= 'a' and &lt;= the first one.</span>
<span class="keyword">auto</span> <span class="identifier">set_last_char</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">_globals</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">).</span><span class="identifier">last_char</span> <span class="special">=</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">};</span>
<span class="keyword">auto</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">[</span><span class="identifier">set_last_char</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="identifier">subparser</span><span class="special">;</span>
</pre>
<p>
        Each callable parser returns a new parser, parameterized using the arguments
        given in the invocation.
      </p>
<p>
        This table lists all the Boost.Parser parsers. For the callable parsers,
        a separate entry exists for each possible arity of arguments. For a parser
        <code class="computeroutput"><span class="identifier">p</span></code>, if there is no entry for
        <code class="computeroutput"><span class="identifier">p</span></code> without arguments, <code class="computeroutput"><span class="identifier">p</span></code> is a function, and cannot itself be used
        as a parser; it must be called. In the table below:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            each entry is a global object usable directly in your parsers, unless
            otherwise noted;
          </li>
<li class="listitem">
            "code point" is used to refer to the elements of the input
            range, which assumes that the parse is being done in the Unicode-aware
            code path (if the parse is being done in the non-Unicode code path, read
            "code point" as "<code class="computeroutput"><span class="keyword">char</span></code>");
          </li>
<li class="listitem">
            <span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><code class="computeroutput"><span class="special">()</span></code>
            is a notional macro that expands to the resolution of parse argument
            or evaluation of a parse predicate (see <a class="link" href="tutorial.html#boost_parser.tutorial.the_parsers_and_their_uses" title="The Parsers And Their Uses">The
            Parsers And Their Uses</a>);
          </li>
<li class="listitem">
            "<code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">pred</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">true</span></code>"
            is a shorthand notation for "<code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">pred</span><span class="special">)</span></code> is contextually convertible to <code class="computeroutput"><span class="keyword">bool</span></code> and <code class="computeroutput"><span class="keyword">true</span></code>";
            likewise for <code class="computeroutput"><span class="keyword">false</span></code>;
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">c</span></code> is a character of type
            <code class="computeroutput"><span class="keyword">char</span></code>, <code class="computeroutput"><span class="identifier">char8_t</span></code>,
            or <code class="computeroutput"><span class="keyword">char32_t</span></code>;
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">str</span></code> is a string literal
            of type <code class="computeroutput"><span class="keyword">char</span> <span class="keyword">const</span><span class="special">[]</span></code>, <code class="computeroutput"><span class="identifier">char8_t</span>
            <span class="keyword">const</span> <span class="special">[]</span></code>,
            or <code class="computeroutput"><span class="keyword">char32_t</span> <span class="keyword">const</span>
            <span class="special">[]</span></code>;
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">pred</span></code> is a parse predicate;
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">arg0</span></code>, <code class="computeroutput"><span class="identifier">arg1</span></code>,
            <code class="computeroutput"><span class="identifier">arg2</span></code>, ... are parse arguments;
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">a</span></code> is a semantic action;
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">r</span></code> is an object whose
            type models <code class="computeroutput"><span class="identifier">parsable_range</span></code>;
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">p</span></code>, <code class="computeroutput"><span class="identifier">p1</span></code>,
            <code class="computeroutput"><span class="identifier">p2</span></code>, ... are parsers;
            and
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">escapes</span></code> is a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols&lt;T&gt;</a></code> object, where <code class="computeroutput"><span class="identifier">T</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
            or <code class="computeroutput"><span class="keyword">char32_t</span></code>.
          </li>
</ul></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top">
<p>
          The definition of <code class="computeroutput"><span class="identifier">parsable_range</span></code>
          is:
        </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">concept</span> <span class="identifier">parsable_range</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ranges</span><span class="special">::</span><span class="identifier">forward_range</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&amp;&amp;</span>
    <span class="identifier">code_unit</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ranges</span><span class="special">::</span><span class="identifier">range_value_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;;</span>
</pre>
<p>
        </p>
</td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          Some of the parsers in this table consume no input. All parsers consume
          the input they match unless otherwise stated in the table below.
        </p></td></tr>
</table></div>
<div class="table">
<a name="boost_parser.tutorial.the_parsers_and_their_uses.t0"></a><p class="title"><b>Table 25.6. Parsers and Their Semantics</b></p>
<div class="table-contents"><table class="table" summary="Parsers and Their Semantics">
<colgroup>
<col>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th>
                <p>
                  Parser
                </p>
              </th>
<th>
                <p>
                  Semantics
                </p>
              </th>
<th>
                <p>
                  Attribute Type
                </p>
              </th>
<th>
                <p>
                  Notes
                </p>
              </th>
</tr></thead>
<tbody>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches <span class="emphasis"><em>epsilon</em></span>, the empty string. Always
                  matches, and consumes no input.
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
                <p>
                  Matching <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                  an unlimited number of times creates an infinite loop, which is
                  undefined behavior in C++. Boost.Parser will assert in debug mode
                  when it encounters <code class="computeroutput"><span class="special">*</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>,
                  <code class="computeroutput"><span class="special">+</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>, etc
                  (this applies to unconditional <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code> only).
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a><span class="special">(</span><span class="identifier">pred</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Fails to match the input if <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">pred</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">false</span></code>. Otherwise, the semantics
                  are those of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>.
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a13a98612c59d598c30d400ff92c7765f.html" title="Global ws">ws</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a single whitespace code point (see note), according to
                  the Unicode White_Space property.
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
                <p>
                  For more info, see the <a href="https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt" target="_top">Unicode
                  properties</a>. <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a13a98612c59d598c30d400ff92c7765f.html" title="Global ws">ws</a></code> may consume one
                  code point or two. It only consumes two code points when it matches
                  <code class="computeroutput"><span class="string">"\r\n"</span></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a15e2b8331566a0b97dad680ac4855004.html" title="Global eol">eol</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a single newline (see note), following the "hard"
                  line breaks in the Unicode line breaking algorithm.
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
                <p>
                  For more info, see the <a href="https://unicode.org/reports/tr14" target="_top">Unicode
                  Line Breaking Algorithm</a>. <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a15e2b8331566a0b97dad680ac4855004.html" title="Global eol">eol</a></code> may consume
                  one code point or two. It only consumes two code points when it
                  matches <code class="computeroutput"><span class="string">"\r\n"</span></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aeba0f48cb171e5e5f121d8ed274a43d5.html" title="Global eoi">eoi</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches only at the end of input, and consumes no input.
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a18903d5e72b8a429e91152e4e57c6e68.html" title="Function template attr">attr</a></code><code class="computeroutput"><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Always matches, and consumes no input. Generates the attribute
                  <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">decltype</span><span class="special">(</span><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">))</span></code>.
                </p>
              </td>
<td>
                <p>
                  An important use case for <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1attribute.html" title="Struct template attribute">attribute</a></code>
                  is to provide a default attribute value as a trailing alternative.
                  For instance, an <span class="bold"><strong>optional</strong></span> comma-delmited
                  list is: <code class="computeroutput"><span class="identifier">int_</span> <span class="special">%</span> <span class="char">','</span> <span class="special">|</span> <span class="identifier">attr</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;)</span></code>. Without the "<code class="computeroutput"><span class="special">|</span> <span class="identifier">attr</span><span class="special">(...)</span></code>", at least one <code class="computeroutput"><span class="identifier">int_</span></code> match would be required.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches any single code point.
                </p>
              </td>
<td>
                <p>
                  The code point type in Unicode parsing, or <code class="computeroutput"><span class="keyword">char</span></code>
                  in non-Unicode parsing. See <a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation" title="Attribute Generation">Attribute
                  Generation</a>.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the code point <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  The code point type in Unicode parsing, or <code class="computeroutput"><span class="keyword">char</span></code>
                  in non-Unicode parsing. See <a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation" title="Attribute Generation">Attribute
                  Generation</a>.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">,</span> <span class="identifier">arg1</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches the next code point <code class="computeroutput"><span class="identifier">n</span></code>
                  in the input, if <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span> <span class="special">&lt;=</span>
                  <span class="identifier">n</span> <span class="special">&amp;&amp;</span>
                  <span class="identifier">n</span> <span class="special">&lt;=</span>
                  <span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg1</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  The code point type in Unicode parsing, or <code class="computeroutput"><span class="keyword">char</span></code>
                  in non-Unicode parsing. See <a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation" title="Attribute Generation">Attribute
                  Generation</a>.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a><span class="special">(</span><span class="identifier">r</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches the next code point <code class="computeroutput"><span class="identifier">n</span></code>
                  in the input, if <code class="computeroutput"><span class="identifier">n</span></code>
                  is one of the code points in <code class="computeroutput"><span class="identifier">r</span></code>.
                </p>
              </td>
<td>
                <p>
                  The code point type in Unicode parsing, or <code class="computeroutput"><span class="keyword">char</span></code>
                  in non-Unicode parsing. See <a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation" title="Attribute Generation">Attribute
                  Generation</a>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">r</span></code> is taken to be
                  in a UTF encoding. The exact UTF used depends on <code class="computeroutput"><span class="identifier">r</span></code>'s element type. If you do not
                  pass UTF encoded ranges for <code class="computeroutput"><span class="identifier">r</span></code>,
                  the behavior of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code> is undefined.
                  Note that ASCII is a subset of UTF-8, so ASCII is fine. EBCDIC
                  is not. <code class="computeroutput"><span class="identifier">r</span></code> is not
                  copied; a reference to it is taken. The lifetime of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a><span class="special">(</span><span class="identifier">r</span><span class="special">)</span></code> must be within the lifetime of
                  <code class="computeroutput"><span class="identifier">r</span></code>. This overload
                  of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>
                  does <span class="bold"><strong>not</strong></span> take parse arguments.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a3d982dd5003327f579e689e9fbbf7cb4.html" title="Global cp">cp</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a single code point.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">char32_t</span></code>
                </p>
              </td>
<td>
                <p>
                  Similar to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>, but with
                  a fixed <code class="computeroutput"><span class="keyword">char32_t</span></code> attribute
                  type; <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a3d982dd5003327f579e689e9fbbf7cb4.html" title="Global cp">cp</a></code>
                  has all the same call operator overloads as <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>, though they
                  are not repeated here, for brevity.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1adf23d22a6b9aa56e8e5d5c5bc2e97881.html" title="Global cu">cu</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a single code point.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">char</span></code>
                </p>
              </td>
<td>
                <p>
                  Similar to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>, but with
                  a fixed <code class="computeroutput"><span class="keyword">char</span></code> attribute
                  type; <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1adf23d22a6b9aa56e8e5d5c5bc2e97881.html" title="Global cu">cu</a></code>
                  has all the same call operator overloads as <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>, though they
                  are not repeated here, for brevity. Even though the name "<code class="computeroutput"><span class="identifier">cu</span></code>" suggests that this parser
                  match at the code unit level, it does not. The name refers to the
                  attribute type generated, much like the names <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aebfca0484fcebac2789c946c6a93b116.html" title="Global int_">int_</a></code> versus <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a7399c57e54ceedc43f5978ac51618a.html" title="Global uint_">uint_</a></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6b2b76f815ee8ea0b5c027335a21b31e.html" title="Global blank">blank</a></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a13a98612c59d598c30d400ff92c7765f.html" title="Global ws">ws</a> <span class="special">-</span>
                  <a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a15e2b8331566a0b97dad680ac4855004.html" title="Global eol">eol</a></code>.
                </p>
              </td>
<td>
                <p>
                  The code point type in Unicode parsing, or <code class="computeroutput"><span class="keyword">char</span></code>
                  in non-Unicode parsing. See the entry for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6c63e7988a7db1d57157d1d4e3d7bd62.html" title="Global control">control</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a single control-character code point.
                </p>
              </td>
<td>
                <p>
                  The code point type in Unicode parsing, or <code class="computeroutput"><span class="keyword">char</span></code>
                  in non-Unicode parsing. See the entry for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aea87ed3dc3b9924397789d49c42cf531.html" title="Global digit">digit</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a single decimal digit code point.
                </p>
              </td>
<td>
                <p>
                  The code point type in Unicode parsing, or <code class="computeroutput"><span class="keyword">char</span></code>
                  in non-Unicode parsing. See the entry for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae199fb8b2d014d07be3376c2664615da.html" title="Global punct">punct</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a single punctuation code point.
                </p>
              </td>
<td>
                <p>
                  The code point type in Unicode parsing, or <code class="computeroutput"><span class="keyword">char</span></code>
                  in non-Unicode parsing. See the entry for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa22c5cfd498f2947edd319e86d85815f.html" title="Global symb">symb</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a single symbol code point.
                </p>
              </td>
<td>
                <p>
                  The code point type in Unicode parsing, or <code class="computeroutput"><span class="keyword">char</span></code>
                  in non-Unicode parsing. See the entry for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2b3a06a86aa310c3bfec9de34e7daef4.html" title="Global hex_digit">hex_digit</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a single hexidecimal digit code point.
                </p>
              </td>
<td>
                <p>
                  The code point type in Unicode parsing, or <code class="computeroutput"><span class="keyword">char</span></code>
                  in non-Unicode parsing. See the entry for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a30c056d60e15f4434b56739d48f578db.html" title="Global lower">lower</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a single lower-case code point.
                </p>
              </td>
<td>
                <p>
                  The code point type in Unicode parsing, or <code class="computeroutput"><span class="keyword">char</span></code>
                  in non-Unicode parsing. See the entry for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7c75578dd1e7556cd861ed6aff46c4c5.html" title="Global upper">upper</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a single upper-case code point.
                </p>
              </td>
<td>
                <p>
                  The code point type in Unicode parsing, or <code class="computeroutput"><span class="keyword">char</span></code>
                  in non-Unicode parsing. See the entry for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa8c123b0cbde389f5d5eaf353169ef09.html" title="Function lit">lit</a></code><code class="computeroutput"><span class="special">(</span><span class="identifier">c</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the given code point <code class="computeroutput"><span class="identifier">c</span></code>.
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa8c123b0cbde389f5d5eaf353169ef09.html" title="Function lit">lit()</a></code> does <span class="bold"><strong>not</strong></span> take parse arguments.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">c_l</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the given code point <code class="computeroutput"><span class="identifier">c</span></code>.
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
                <p>
                  This is a <a href="https://en.cppreference.com/w/cpp/language/user_literal" target="_top">UDL</a>
                  that represents <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa8c123b0cbde389f5d5eaf353169ef09.html" title="Function lit">lit</a><span class="special">(</span><span class="identifier">c</span><span class="special">)</span></code>,
                  for example <code class="computeroutput"><span class="char">'F'</span><span class="identifier">_l</span></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa8c123b0cbde389f5d5eaf353169ef09.html" title="Function lit">lit</a></code><code class="computeroutput"><span class="special">(</span><span class="identifier">r</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the given string <code class="computeroutput"><span class="identifier">r</span></code>.
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa8c123b0cbde389f5d5eaf353169ef09.html" title="Function lit">lit()</a></code> does <span class="bold"><strong>not</strong></span> take parse arguments.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">str_l</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the given string <code class="computeroutput"><span class="identifier">str</span></code>.
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
                <p>
                  This is a <a href="https://en.cppreference.com/w/cpp/language/user_literal" target="_top">UDL</a>
                  that represents <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa8c123b0cbde389f5d5eaf353169ef09.html" title="Function lit">lit</a><span class="special">(</span><span class="identifier">s</span><span class="special">)</span></code>,
                  for example <code class="computeroutput"><span class="string">"a string"</span><span class="identifier">_l</span></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7e079d756d52cf5fc94cbdca53bb8b4f.html" title="Function template string">string</a><span class="special">(</span><span class="identifier">r</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly <code class="computeroutput"><span class="identifier">r</span></code>,
                  and generates the match as an attribute.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7e079d756d52cf5fc94cbdca53bb8b4f.html" title="Function template string">string()</a></code> does <span class="bold"><strong>not</strong></span> take parse arguments.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">str_p</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly <code class="computeroutput"><span class="identifier">str</span></code>,
                  and generates the match as an attribute.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
                </p>
              </td>
<td>
                <p>
                  This is a <a href="https://en.cppreference.com/w/cpp/language/user_literal" target="_top">UDL</a>
                  that represents <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7e079d756d52cf5fc94cbdca53bb8b4f.html" title="Function template string">string</a><span class="special">(</span><span class="identifier">s</span><span class="special">)</span></code>, for example <code class="computeroutput"><span class="string">"a
                  string"</span><span class="identifier">_p</span></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab79cf11acb9757d1e82abbc6ac31bf51.html" title="Global bool_">bool_</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches <code class="computeroutput"><span class="string">"true"</span></code>
                  or <code class="computeroutput"><span class="string">"false"</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">bool</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abbe29c0334264fd28535b8a3abec39e2.html" title="Global bin">bin</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a binary unsigned integral value.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">int</span></code>
                </p>
              </td>
<td>
                <p>
                  For example, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abbe29c0334264fd28535b8a3abec39e2.html" title="Global bin">bin</a></code> would match
                  <code class="computeroutput"><span class="string">"101"</span></code>, and
                  generate an attribute of <code class="computeroutput"><span class="number">5u</span></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abbe29c0334264fd28535b8a3abec39e2.html" title="Global bin">bin</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the binary unsigned integral value <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">int</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab1dbbcfeb807e261ffaaf0224e21f7ca.html" title="Global oct">oct</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches an octal unsigned integral value.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">int</span></code>
                </p>
              </td>
<td>
                <p>
                  For example, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab1dbbcfeb807e261ffaaf0224e21f7ca.html" title="Global oct">oct</a></code> would match
                  <code class="computeroutput"><span class="string">"31"</span></code>, and
                  generate an attribute of <code class="computeroutput"><span class="number">25u</span></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab1dbbcfeb807e261ffaaf0224e21f7ca.html" title="Global oct">oct</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the octal unsigned integral value <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">int</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1af7c7911157c8d43d4328ec6342a77a31.html" title="Global hex">hex</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a hexadecimal unsigned integral value.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">int</span></code>
                </p>
              </td>
<td>
                <p>
                  For example, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1af7c7911157c8d43d4328ec6342a77a31.html" title="Global hex">hex</a></code> would match
                  <code class="computeroutput"><span class="string">"ff"</span></code>, and
                  generate an attribute of <code class="computeroutput"><span class="number">255u</span></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1af7c7911157c8d43d4328ec6342a77a31.html" title="Global hex">hex</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the hexadecimal unsigned integral value <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">int</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a591f036e613e107e00e5136226c02ec8.html" title="Global ushort_">ushort_</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches an unsigned integral value.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">short</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a591f036e613e107e00e5136226c02ec8.html" title="Global ushort_">ushort_</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the unsigned integral value <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">short</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a7399c57e54ceedc43f5978ac51618a.html" title="Global uint_">uint_</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches an unsigned integral value.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">int</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a7399c57e54ceedc43f5978ac51618a.html" title="Global uint_">uint_</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the unsigned integral value <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">int</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6225883e4382da031c727b333a585f58.html" title="Global ulong_">ulong_</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches an unsigned integral value.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">long</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6225883e4382da031c727b333a585f58.html" title="Global ulong_">ulong_</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the unsigned integral value <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">long</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ac1d1fef19c32c6b74cdc3857ffa9feb8.html" title="Global ulong_long">ulong_long</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches an unsigned integral value.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">long</span>
                  <span class="keyword">long</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ac1d1fef19c32c6b74cdc3857ffa9feb8.html" title="Global ulong_long">ulong_long</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the unsigned integral value <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">long</span>
                  <span class="keyword">long</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ac1331c03e89ff310052d9a38bc75621c.html" title="Global short_">short_</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a signed integral value.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">short</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ac1331c03e89ff310052d9a38bc75621c.html" title="Global short_">short_</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the signed integral value <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">short</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aebfca0484fcebac2789c946c6a93b116.html" title="Global int_">int_</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a signed integral value.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">int</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aebfca0484fcebac2789c946c6a93b116.html" title="Global int_">int_</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the signed integral value <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">int</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1afdbc039990e44df91b04ef713b6d6058.html" title="Global long_">long_</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a signed integral value.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">long</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1afdbc039990e44df91b04ef713b6d6058.html" title="Global long_">long_</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the signed integral value <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">long</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a85f44231c5106a739257b24a2b6a40ff.html" title="Global long_long">long_long</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a signed integral value.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">long</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a85f44231c5106a739257b24a2b6a40ff.html" title="Global long_long">long_long</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches exactly the signed integral value <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">long</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2c6a3d18060166bd926f3150327819a4.html" title="Global float_">float_</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a floating-point number. <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2c6a3d18060166bd926f3150327819a4.html" title="Global float_">float_</a></code> uses parsing
                  implementation details from <a href="https://www.boost.org/doc/libs/release/libs/spirit" target="_top">Boost.Spirit</a>.
                  The specifics of what formats are accepted can be found in their
                  <a href="https://www.boost.org/doc/libs/release/libs/spirit/doc/html/spirit/qi/reference/numeric/real.html" target="_top">real
                  number parsers</a>. Note that only the default <code class="computeroutput"><span class="identifier">RealPolicies</span></code> is supported by
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2c6a3d18060166bd926f3150327819a4.html" title="Global float_">float_</a></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">float</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6e37283853b49605ec05b4a1969eaaac.html" title="Global double_">double_</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches a floating-point number. <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6e37283853b49605ec05b4a1969eaaac.html" title="Global double_">double_</a></code> uses parsing
                  implementation details from <a href="https://www.boost.org/doc/libs/release/libs/spirit" target="_top">Boost.Spirit</a>.
                  The specifics of what formats are accepted can be found in their
                  <a href="https://www.boost.org/doc/libs/release/libs/spirit/doc/html/spirit/qi/reference/numeric/real.html" target="_top">real
                  number parsers</a>. Note that only the default <code class="computeroutput"><span class="identifier">RealPolicies</span></code> is supported by
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6e37283853b49605ec05b4a1969eaaac.html" title="Global double_">double_</a></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">double</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad95e37e5cf4468149eec5f774ad977f3.html" title="Function template repeat">repeat</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)[</span><span class="identifier">p</span><span class="special">]</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches iff <code class="computeroutput"><span class="identifier">p</span></code> matches
                  exactly <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code> times.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
<td>
                <p>
                  The special value <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5b813aca4da43df067039a46c9565376.html" title="Global Inf">Inf</a></code> may be used;
                  it indicates unlimited repetition. <code class="computeroutput"><span class="keyword">decltype</span><span class="special">(</span><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">))</span></code> must be implicitly convertible
                  to <code class="computeroutput"><span class="identifier">int64_t</span></code>. Matching
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                  an unlimited number of times creates an infinite loop, which is
                  undefined behavior in C++. Boost.Parser will assert in debug mode
                  when it encounters <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad95e37e5cf4468149eec5f774ad977f3.html" title="Function template repeat">repeat</a><span class="special">(</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5b813aca4da43df067039a46c9565376.html" title="Global Inf">Inf</a><span class="special">)[</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a><span class="special">]</span></code> (this applies to unconditional
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                  only).
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad95e37e5cf4468149eec5f774ad977f3.html" title="Function template repeat">repeat</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">,</span> <span class="identifier">arg1</span><span class="special">)[</span><span class="identifier">p</span><span class="special">]</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches iff <code class="computeroutput"><span class="identifier">p</span></code> matches
                  between <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code> and <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg1</span><span class="special">)</span></code> times, inclusively.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
<td>
                <p>
                  The special value <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5b813aca4da43df067039a46c9565376.html" title="Global Inf">Inf</a></code> may be used
                  for the upper bound; it indicates unlimited repetition. <code class="computeroutput"><span class="keyword">decltype</span><span class="special">(</span><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">))</span></code> and <code class="computeroutput"><span class="keyword">decltype</span><span class="special">(</span><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg1</span><span class="special">))</span></code> each must be implicitly convertible
                  to <code class="computeroutput"><span class="identifier">int64_t</span></code>. Matching
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                  an unlimited number of times creates an infinite loop, which is
                  undefined behavior in C++. Boost.Parser will assert in debug mode
                  when it encounters <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad95e37e5cf4468149eec5f774ad977f3.html" title="Function template repeat">repeat</a><span class="special">(</span><span class="identifier">n</span><span class="special">,</span> <a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5b813aca4da43df067039a46c9565376.html" title="Global Inf">Inf</a><span class="special">)[</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a><span class="special">]</span></code> (this applies to unconditional
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                  only).
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc7ab7877a423d66c6a8fb49a702bd5.html" title="Function template if_">if_</a><span class="special">(</span><span class="identifier">pred</span><span class="special">)[</span><span class="identifier">p</span><span class="special">]</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a><span class="special">(</span><span class="identifier">pred</span><span class="special">)</span>
                  <span class="special">&gt;&gt;</span> <span class="identifier">p</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
<td>
                <p>
                  It is an error to write <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc7ab7877a423d66c6a8fb49a702bd5.html" title="Function template if_">if_</a><span class="special">(</span><span class="identifier">pred</span><span class="special">)</span></code>.
                  That is, it is an error to omit the conditionally matched parser
                  <code class="computeroutput"><span class="identifier">p</span></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad0e7ed5270417b766644b5197a469e7c.html" title="Function template switch_">switch_</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)(</span><span class="identifier">arg1</span><span class="special">,</span> <span class="identifier">p1</span><span class="special">)(</span><span class="identifier">arg2</span><span class="special">,</span> <span class="identifier">p2</span><span class="special">)</span> <span class="special">...</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><span class="identifier">p1</span></code>
                  when <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span> <span class="special">==</span> <span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg1</span><span class="special">)</span></code>, <code class="computeroutput"><span class="identifier">p2</span></code>
                  when <code class="computeroutput"><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span> <span class="special">==</span> <span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">arg2</span><span class="special">)</span></code>, etc. If there is such no <code class="computeroutput"><span class="identifier">argN</span></code>, the behavior of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad0e7ed5270417b766644b5197a469e7c.html" title="Function template switch_">switch_()</a></code> is undefined.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">),</span> <span class="special">...&gt;</span></code>
                </p>
              </td>
<td>
                <p>
                  It is an error to write <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad0e7ed5270417b766644b5197a469e7c.html" title="Function template switch_">switch_</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)</span></code>. That is, it is an error to omit
                  the conditionally matched parsers <code class="computeroutput"><span class="identifier">p1</span></code>,
                  <code class="computeroutput"><span class="identifier">p2</span></code>, ....
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols&lt;T&gt;</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code>
                  is an associative container of key, value pairs. Each key is a
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> and each value has type
                  <code class="computeroutput"><span class="identifier">T</span></code>. In the Unicode
                  parsing path, the strings are considered to be UTF-8 encoded; in
                  the non-Unicode path, no encoding is assumed. <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code> Matches the
                  longest prefix <code class="computeroutput"><span class="identifier">pre</span></code>
                  of the input that is equal to one of the keys <code class="computeroutput"><span class="identifier">k</span></code>.
                  If the length <code class="computeroutput"><span class="identifier">len</span></code>
                  of <code class="computeroutput"><span class="identifier">pre</span></code> is zero,
                  and there is no zero-length key, it does not match the input. If
                  <code class="computeroutput"><span class="identifier">len</span></code> is positive,
                  the generated attribute is the value associated with <code class="computeroutput"><span class="identifier">k</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">T</span></code>
                </p>
              </td>
<td>
                <p>
                  Unlike the other entries in this table, <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code> is a type,
                  not an object.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa2226d7c167c672d4c2c0720766be73b.html" title="Global quoted_string">quoted_string</a></code>
                </p>
              </td>
<td>
                <p>
                  Matches <code class="computeroutput"><span class="char">'"'</span></code>, followed
                  by zero or more characters, followed by <code class="computeroutput"><span class="char">'"'</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
                </p>
              </td>
<td>
                <p>
                  The result does not include the quotes. A quote within the string
                  can be written by escaping it with a backslash. A backslash within
                  the string can be written by writing two consecutive backslashes.
                  Any other use of a backslash will fail the parse. Skipping is disabled
                  while parsing the entire string, as if using <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc4518d7b420ac61d70ea3405ec74fd.html" title="Global lexeme">lexeme[]</a></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa2226d7c167c672d4c2c0720766be73b.html" title="Global quoted_string">quoted_string</a><span class="special">(</span><span class="identifier">c</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches <code class="computeroutput"><span class="identifier">c</span></code>, followed
                  by zero or more characters, followed by <code class="computeroutput"><span class="identifier">c</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
                </p>
              </td>
<td>
                <p>
                  The result does not include the <code class="computeroutput"><span class="identifier">c</span></code>
                  quotes. A <code class="computeroutput"><span class="identifier">c</span></code> within
                  the string can be written by escaping it with a backslash. A backslash
                  within the string can be written by writing two consecutive backslashes.
                  Any other use of a backslash will fail the parse. Skipping is disabled
                  while parsing the entire string, as if using <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc4518d7b420ac61d70ea3405ec74fd.html" title="Global lexeme">lexeme[]</a></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa2226d7c167c672d4c2c0720766be73b.html" title="Global quoted_string">quoted_string</a><span class="special">(</span><span class="identifier">r</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches some character <code class="computeroutput"><span class="identifier">Q</span></code>
                  in <code class="computeroutput"><span class="identifier">r</span></code>, followed
                  by zero or more characters, followed by <code class="computeroutput"><span class="identifier">Q</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
                </p>
              </td>
<td>
                <p>
                  The result does not include the <code class="computeroutput"><span class="identifier">Q</span></code>
                  quotes. A <code class="computeroutput"><span class="identifier">Q</span></code> within
                  the string can be written by escaping it with a backslash. A backslash
                  within the string can be written by writing two consecutive backslashes.
                  Any other use of a backslash will fail the parse. Skipping is disabled
                  while parsing the entire string, as if using <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc4518d7b420ac61d70ea3405ec74fd.html" title="Global lexeme">lexeme[]</a></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa2226d7c167c672d4c2c0720766be73b.html" title="Global quoted_string">quoted_string</a><span class="special">(</span><span class="identifier">c</span><span class="special">,</span> <span class="identifier">symbols</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches <code class="computeroutput"><span class="identifier">c</span></code>, followed
                  by zero or more characters, followed by <code class="computeroutput"><span class="identifier">c</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
                </p>
              </td>
<td>
                <p>
                  The result does not include the <code class="computeroutput"><span class="identifier">c</span></code>
                  quotes. A <code class="computeroutput"><span class="identifier">c</span></code> within
                  the string can be written by escaping it with a backslash. A backslash
                  within the string can be written by writing two consecutive backslashes.
                  A backslash followed by a successful match using <code class="computeroutput"><span class="identifier">symbols</span></code> will be interpreted as
                  the corresponding value produced by <code class="computeroutput"><span class="identifier">symbols</span></code>.
                  Any other use of a backslash will fail the parse. Skipping is disabled
                  while parsing the entire string, as if using <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc4518d7b420ac61d70ea3405ec74fd.html" title="Global lexeme">lexeme[]</a></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa2226d7c167c672d4c2c0720766be73b.html" title="Global quoted_string">quoted_string</a><span class="special">(</span><span class="identifier">r</span><span class="special">,</span> <span class="identifier">symbols</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches some character <code class="computeroutput"><span class="identifier">Q</span></code>
                  in <code class="computeroutput"><span class="identifier">r</span></code>, followed
                  by zero or more characters, followed by <code class="computeroutput"><span class="identifier">Q</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
                </p>
              </td>
<td>
                <p>
                  The result does not include the <code class="computeroutput"><span class="identifier">Q</span></code>
                  quotes. A <code class="computeroutput"><span class="identifier">Q</span></code> within
                  the string can be written by escaping it with a backslash. A backslash
                  within the string can be written by writing two consecutive backslashes.
                  A backslash followed by a successful match using <code class="computeroutput"><span class="identifier">symbols</span></code> will be interpreted as
                  the corresponding value produced by <code class="computeroutput"><span class="identifier">symbols</span></code>.
                  Any other use of a backslash will fail the parse. Skipping is disabled
                  while parsing the entire string, as if using <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc4518d7b420ac61d70ea3405ec74fd.html" title="Global lexeme">lexeme[]</a></code>.
                </p>
              </td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          All the character parsers, like <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a3d982dd5003327f579e689e9fbbf7cb4.html" title="Global cp">cp</a></code> and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1adf23d22a6b9aa56e8e5d5c5bc2e97881.html" title="Global cu">cu</a></code> produce either <code class="computeroutput"><span class="keyword">char</span></code> or <code class="computeroutput"><span class="keyword">char32_t</span></code>
          attributes. So when you see "<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
          if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is
          <code class="computeroutput"><span class="keyword">char</span></code> or <code class="computeroutput"><span class="keyword">char32_t</span></code>,
          otherwise <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>"
          in the table above, that effectively means that every sequences of character
          attributes get turned into a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
          The only time this does not happen is when you introduce your own rules
          with attributes using another character type (or use <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1attribute.html" title="Struct template attribute">attribute</a></code> to do so).
        </p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          A slightly more complete description of the attributes generated by these
          parsers is in a subsequent section. The attributes are repeated here so
          you can use see all the properties of the parsers in one place.
        </p></td></tr>
</table></div>
<p>
        If you have an integral type <code class="computeroutput"><span class="identifier">IntType</span></code>
        that is not covered by any of the Boost.Parser parsers, you can use a more
        verbose declaration to declare a parser for <code class="computeroutput"><span class="identifier">IntType</span></code>.
        If <code class="computeroutput"><span class="identifier">IntType</span></code> were unsigned,
        you would use <code class="computeroutput"><span class="identifier">uint_parser</span></code>.
        If it were signed, you would use <code class="computeroutput"><span class="identifier">int_parser</span></code>.
        For example:
      </p>
<pre class="programlisting"><span class="keyword">constexpr</span> <span class="identifier">parser_interface</span><span class="special">&lt;</span><span class="identifier">int_parser</span><span class="special">&lt;</span><span class="identifier">IntType</span><span class="special">&gt;&gt;</span> <span class="identifier">hex_int</span><span class="special">;</span>
</pre>
<p>
        <code class="computeroutput"><span class="identifier">uint_parser</span></code> and <code class="computeroutput"><span class="identifier">int_parser</span></code> accept three more non-type template
        parameters after the type parameter. They are <code class="computeroutput"><span class="identifier">Radix</span></code>,
        <code class="computeroutput"><span class="identifier">MinDigits</span></code>, and <code class="computeroutput"><span class="identifier">MaxDigits</span></code>. <code class="computeroutput"><span class="identifier">Radix</span></code>
        defaults to <code class="computeroutput"><span class="number">10</span></code>, <code class="computeroutput"><span class="identifier">MinDigits</span></code> to <code class="computeroutput"><span class="number">1</span></code>,
        and <code class="computeroutput"><span class="identifier">MaxDigits</span></code> to <code class="computeroutput"><span class="special">-</span><span class="number">1</span></code>, which is
        a sentinel value meaning that there is no max number of digits.
      </p>
<p>
        So, if you wanted to parse exactly eight hexadecimal digits in a row in order
        to recognize Unicode character literals like C++ has (e.g. <code class="computeroutput"><span class="special">\</span><span class="identifier">Udeadbeef</span></code>),
        you could use this parser for the digits at the end:
      </p>
<pre class="programlisting"><span class="keyword">constexpr</span> <span class="identifier">parser_interface</span><span class="special">&lt;</span><span class="identifier">uint_parser</span><span class="special">&lt;</span><span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">,</span> <span class="number">16</span><span class="special">,</span> <span class="number">8</span><span class="special">,</span> <span class="number">8</span><span class="special">&gt;&gt;</span> <span class="identifier">hex_int</span><span class="special">;</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.directives"></a><a class="link" href="tutorial.html#boost_parser.tutorial.directives" title="Directives">Directives</a>
</h3></div></div></div>
<p>
        A directive is an element of your parser that doesn't have any meaning by
        itself. Some are second-order parsers that need a first-order parser to do
        the actual parsing. Others influence the parse in some way. You can often
        spot a directive lexically by its use of <code class="computeroutput"><span class="special">[]</span></code>;
        directives always <code class="computeroutput"><span class="special">[]</span></code>. Non-directives
        might, but only when attaching a semantic action.
      </p>
<p>
        The directives that are second order parsers are technically directives,
        but since they are also used to create parsers, it is more useful just to
        focus on that. The directives <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad95e37e5cf4468149eec5f774ad977f3.html" title="Function template repeat">repeat()</a></code>
        and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc7ab7877a423d66c6a8fb49a702bd5.html" title="Function template if_">if_()</a></code> were already described in
        the section on parsers; we won't say much about them here.
      </p>
<h5>
<a name="boost_parser.tutorial.directives.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.directives.interaction_with_sequence__alternative__and_permutation_parsers"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.directives.interaction_with_sequence__alternative__and_permutation_parsers">Interaction
        with sequence, alternative, and permutation parsers</a>
      </h5>
<p>
        Sequence, alternative, and permutation parsers do not nest in most cases.
        (Let's consider just sequence parsers to keep thinkgs simple, but most of
        this logic applies to alternative parsers as well.) <code class="computeroutput"><span class="identifier">a</span>
        <span class="special">&gt;&gt;</span> <span class="identifier">b</span>
        <span class="special">&gt;&gt;</span> <span class="identifier">c</span></code>
        is the same as <code class="computeroutput"><span class="special">(</span><span class="identifier">a</span>
        <span class="special">&gt;&gt;</span> <span class="identifier">b</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="identifier">c</span></code> and <code class="computeroutput"><span class="identifier">a</span>
        <span class="special">&gt;&gt;</span> <span class="special">(</span><span class="identifier">b</span> <span class="special">&gt;&gt;</span> <span class="identifier">c</span><span class="special">)</span></code>, and
        they are each represented by a single <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1seq__parser.html" title="Struct template seq_parser">seq_parser</a></code> with three subparsers,
        <code class="computeroutput"><span class="identifier">a</span></code>, <code class="computeroutput"><span class="identifier">b</span></code>,
        and <code class="computeroutput"><span class="identifier">c</span></code>. However, if something
        prevents two <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1seq__parser.html" title="Struct template seq_parser">seq_parsers</a></code>
        from interacting directly, they <span class="bold"><strong>will</strong></span> nest.
        For instance, <code class="computeroutput"><span class="identifier">lexeme</span><span class="special">[</span><span class="identifier">a</span> <span class="special">&gt;&gt;</span> <span class="identifier">b</span><span class="special">]</span> <span class="special">&gt;&gt;</span>
        <span class="identifier">c</span></code> is a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1seq__parser.html" title="Struct template seq_parser">seq_parser</a></code> containing two parsers,
        <code class="computeroutput"><span class="identifier">lexeme</span><span class="special">[</span><span class="identifier">a</span> <span class="special">&gt;&gt;</span> <span class="identifier">b</span><span class="special">]</span></code> and
        <code class="computeroutput"><span class="identifier">c</span></code>. This is because <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc4518d7b420ac61d70ea3405ec74fd.html" title="Global lexeme">lexeme[]</a></code> takes its given parser and
        wraps it in a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1lexeme__parser.html" title="Struct template lexeme_parser">lexeme_parser</a></code>. This in turn
        turns off the sequence parser combining logic, since both sides of the second
        <code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;&gt;</span></code>
        in <code class="computeroutput"><span class="identifier">lexeme</span><span class="special">[</span><span class="identifier">a</span> <span class="special">&gt;&gt;</span> <span class="identifier">b</span><span class="special">]</span> <span class="special">&gt;&gt;</span>
        <span class="identifier">c</span></code> are not <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1seq__parser.html" title="Struct template seq_parser">seq_parsers</a></code>. Sequence parsers
        have several rules that govern what the overall attribute type of the parser
        is, based on the positions and attributes of it subparsers (see <a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation" title="Attribute Generation">Attribute
        Generation</a>). Therefore, it's important to know which directives create
        a new parser (and what kind), and which ones do not; this is indicated for
        each directive below.
      </p>
<h5>
<a name="boost_parser.tutorial.directives.h1"></a>
        <span class="phrase"><a name="boost_parser.tutorial.directives.the_directives"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.directives.the_directives">The
        directives</a>
      </h5>
<h5>
<a name="boost_parser.tutorial.directives.h2"></a>
        <span class="phrase"><a name="boost_parser.tutorial.directives._functionname_alt__boost__parser__repeat___code__phrase_role__identifier__repeat__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.directives._functionname_alt__boost__parser__repeat___code__phrase_role__identifier__repeat__phrase__phrase_role__special______phrase___code___functionname_">repeat()</a>
      </h5>
<p>
        See <a class="link" href="tutorial.html#boost_parser.tutorial.the_parsers_and_their_uses" title="The Parsers And Their Uses">The
        Parsers And Their Uses</a>. Creates a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1repeat__parser.html" title="Struct template repeat_parser">repeat_parser</a></code>.
      </p>
<h5>
<a name="boost_parser.tutorial.directives.h3"></a>
        <span class="phrase"><a name="boost_parser.tutorial.directives._functionname_alt__boost__parser__if____code__phrase_role__identifier__if___phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.directives._functionname_alt__boost__parser__if____code__phrase_role__identifier__if___phrase__phrase_role__special______phrase___code___functionname_">if_()</a>
      </h5>
<p>
        See <a class="link" href="tutorial.html#boost_parser.tutorial.the_parsers_and_their_uses" title="The Parsers And Their Uses">The
        Parsers And Their Uses</a>. Creates a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1seq__parser.html" title="Struct template seq_parser">seq_parser</a></code>.
      </p>
<h5>
<a name="boost_parser.tutorial.directives.h4"></a>
        <span class="phrase"><a name="boost_parser.tutorial.directives._globalname_alt__boost__parser__omit___code__phrase_role__identifier__omit__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.directives._globalname_alt__boost__parser__omit___code__phrase_role__identifier__omit__phrase__phrase_role__special______phrase___code___globalname_">omit[]</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aba924d9dafe70d651680058e6004f31e.html" title="Global omit">omit</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>
        disables attribute generation for the parser <code class="computeroutput"><span class="identifier">p</span></code>.
        Not only does <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aba924d9dafe70d651680058e6004f31e.html" title="Global omit">omit</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>
        have no attribute, but any attribute generation work that normally happens
        within <code class="computeroutput"><span class="identifier">p</span></code> is skipped.
      </p>
<p>
        This directive can be useful in cases like this: say you have some fairly
        complicated parser <code class="computeroutput"><span class="identifier">p</span></code> that
        generates a large and expensive-to-construct attribute. Now say that you
        want to write a function that just counts how many times <code class="computeroutput"><span class="identifier">p</span></code>
        can match a string (where the matches are non-overlapping). Instead of using
        <code class="computeroutput"><span class="identifier">p</span></code> directly, and building
        all those attributes, or rewriting <code class="computeroutput"><span class="identifier">p</span></code>
        without the attribute generation, use <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aba924d9dafe70d651680058e6004f31e.html" title="Global omit">omit[]</a></code>.
      </p>
<p>
        Creates an <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1omit__parser.html" title="Struct template omit_parser">omit_parser</a></code>.
      </p>
<h5>
<a name="boost_parser.tutorial.directives.h5"></a>
        <span class="phrase"><a name="boost_parser.tutorial.directives._globalname_alt__boost__parser__raw___code__phrase_role__identifier__raw__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.directives._globalname_alt__boost__parser__raw___code__phrase_role__identifier__raw__phrase__phrase_role__special______phrase___code___globalname_">raw[]</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3960485823df80f6a97f87e811cf7b.html" title="Global raw">raw</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>
        changes the attribute from <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
        to to a view that delimits the subrange of the input that was matched by
        <code class="computeroutput"><span class="identifier">p</span></code>. The type of the view is
        <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1subrange.html" title="Struct template subrange">subrange</a><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;</span></code>,
        where <code class="computeroutput"><span class="identifier">I</span></code> is the type of the
        iterator used within the parse. Note that this may not be the same as the
        iterator type passed to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>.
        For instance, when parsing UTF-8, the iterator passed to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        may be <code class="computeroutput"><span class="identifier">char8_t</span> <span class="keyword">const</span>
        <span class="special">*</span></code>, but within the parse it will be
        a UTF-8 to UTF-32 transcoding (converting) iterator. Just like <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aba924d9dafe70d651680058e6004f31e.html" title="Global omit">omit[]</a></code>, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3960485823df80f6a97f87e811cf7b.html" title="Global raw">raw[]</a></code>
        causes all attribute-generation work within <code class="computeroutput"><span class="identifier">p</span></code>
        to be skipped.
      </p>
<p>
        Similar to the re-use scenario for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aba924d9dafe70d651680058e6004f31e.html" title="Global omit">omit[]</a></code>
        above, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3960485823df80f6a97f87e811cf7b.html" title="Global raw">raw[]</a></code> could be used to find the
        <span class="bold"><strong>locations</strong></span> of all non-overlapping matches
        of <code class="computeroutput"><span class="identifier">p</span></code> in a string.
      </p>
<p>
        Creates a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1raw__parser.html" title="Struct template raw_parser">raw_parser</a></code>.
      </p>
<h5>
<a name="boost_parser.tutorial.directives.h6"></a>
        <span class="phrase"><a name="boost_parser.tutorial.directives._globalname_alt__boost__parser__string_view___code__phrase_role__identifier__string_view__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.directives._globalname_alt__boost__parser__string_view___code__phrase_role__identifier__string_view__phrase__phrase_role__special______phrase___code___globalname_">string_view[]</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a8890ba07e65b9e7b1b0f238e94498d.html" title="Global string_view">string_view</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>
        is very similar to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3960485823df80f6a97f87e811cf7b.html" title="Global raw">raw</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>, except
        that it changes the attribute of <code class="computeroutput"><span class="identifier">p</span></code>
        to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string_view</span><span class="special">&lt;</span><span class="identifier">C</span><span class="special">&gt;</span></code>,
        where <code class="computeroutput"><span class="identifier">C</span></code> is the character
        type of the underlying range being parsed. <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a8890ba07e65b9e7b1b0f238e94498d.html" title="Global string_view">string_view[]</a></code>
        requires that the underlying range being parsed is contiguous. Since this
        can only be detected in C++20 and later, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a8890ba07e65b9e7b1b0f238e94498d.html" title="Global string_view">string_view[]</a></code>
        is not available in C++17 mode.
      </p>
<p>
        Similar to the re-use scenario for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aba924d9dafe70d651680058e6004f31e.html" title="Global omit">omit[]</a></code>
        above, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a8890ba07e65b9e7b1b0f238e94498d.html" title="Global string_view">string_view[]</a></code> could be used to find the
        <span class="bold"><strong>locations</strong></span> of all non-overlapping matches
        of <code class="computeroutput"><span class="identifier">p</span></code> in a string. Whether
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3960485823df80f6a97f87e811cf7b.html" title="Global raw">raw[]</a></code> or <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a8890ba07e65b9e7b1b0f238e94498d.html" title="Global string_view">string_view[]</a></code>
        is more natural to use to report the locations depends on your use case,
        but they are essentially the same.
      </p>
<p>
        Creates a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1string__view__parser.html" title="Struct template string_view_parser">string_view_parser</a></code>.
      </p>
<h5>
<a name="boost_parser.tutorial.directives.h7"></a>
        <span class="phrase"><a name="boost_parser.tutorial.directives._globalname_alt__boost__parser__no_case___code__phrase_role__identifier__no_case__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.directives._globalname_alt__boost__parser__no_case___code__phrase_role__identifier__no_case__phrase__phrase_role__special______phrase___code___globalname_">no_case[]</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a3f4e39c08f5f3a79750e7bcf8b542fdd.html" title="Global no_case">no_case</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>
        enables case-insensitive parsing within the parse of <code class="computeroutput"><span class="identifier">p</span></code>.
        This applies to the text parsed by <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a><span class="special">()</span></code>,
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7e079d756d52cf5fc94cbdca53bb8b4f.html" title="Function template string">string()</a></code>, and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab79cf11acb9757d1e82abbc6ac31bf51.html" title="Global bool_">bool_</a></code> parsers. The number
        parsers are already case-insensitive. The case-insensitivity is achieved
        by doing Unicode case folding on the text being parsed and the values in
        the parser being matched (see note below if you want to know more about Unicode
        case folding). In the non-Unicode code path, a full Unicode case folding
        is not done; instead, only the transformations of values less than <code class="computeroutput"><span class="number">0x100</span></code> are done. Examples:
      </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">parser</span><span class="special">/</span><span class="identifier">transcode_view</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// For as_utfN.</span>

<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">street_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="identifier">u8</span><span class="string">"Tobias Straße"</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(!</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"Tobias Strasse"</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf32</span><span class="special">,</span> <span class="identifier">street_parser</span><span class="special">));</span>             <span class="comment">// No match.</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"Tobias Strasse"</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf32</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">no_case</span><span class="special">[</span><span class="identifier">street_parser</span><span class="special">]));</span> <span class="comment">// Match!</span>

<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">alpha_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">no_case</span><span class="special">[</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">,</span> <span class="char">'z'</span><span class="special">)];</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"a"</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf32</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">no_case</span><span class="special">[</span><span class="identifier">alpha_parser</span><span class="special">]));</span> <span class="comment">// Match!</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"B"</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf32</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">no_case</span><span class="special">[</span><span class="identifier">alpha_parser</span><span class="special">]));</span> <span class="comment">// Match!</span>
</pre>
<p>
        Everything pretty much does what you'd naively expect inside <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a3f4e39c08f5f3a79750e7bcf8b542fdd.html" title="Global no_case">no_case[]</a></code>, except that the two-character
        range version of <code class="computeroutput"><span class="identifier">char_</span></code> has
        a limitation. It only compares a code point from the input to its two arguments
        (e.g. <code class="computeroutput"><span class="char">'a'</span></code> and <code class="computeroutput"><span class="char">'z'</span></code>
        in the example above). It does not do anything special for multi-code point
        case folding expansions. For instance, <code class="computeroutput"><span class="identifier">char_</span><span class="special">(</span><span class="identifier">U</span><span class="char">'ß'</span><span class="special">,</span> <span class="identifier">U</span><span class="char">'ß'</span><span class="special">)</span></code> matches the input <code class="computeroutput"><span class="identifier">U</span><span class="string">"s"</span></code>, which makes sense, since <code class="computeroutput"><span class="identifier">U</span><span class="char">'ß'</span></code> expands
        to <code class="computeroutput"><span class="identifier">U</span><span class="string">"ss"</span></code>.
        However, that same parser <span class="bold"><strong>does not</strong></span> match
        the input <code class="computeroutput"><span class="identifier">U</span><span class="string">"ß"</span></code>!
        In short, stick to pairs of code points that have single-code point case
        folding expansions. If you need to support the multi-expanding code points,
        use the other overload, like: <code class="computeroutput"><span class="identifier">char_</span><span class="special">(</span><span class="identifier">U</span><span class="string">"abcd/*...*/ß"</span><span class="special">)</span></code>.
      </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          Unicode case folding is an operation that makes text uniformly one case,
          and if you do it to two bits of text <code class="computeroutput"><span class="identifier">A</span></code>
          and <code class="computeroutput"><span class="identifier">B</span></code>, then you can compare
          them bitwise to see if they are the same, except of case. Case folding
          may sometimes expand a code point into multiple code points (e.g. case
          folding <code class="computeroutput"><span class="string">"ẞ"</span></code> yields
          <code class="computeroutput"><span class="string">"ss"</span></code>. When such a
          multi-code point expansion occurs, the expanded code points are in the
          NFKC normalization form.
        </p></td></tr>
</table></div>
<p>
        Creates a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1no__case__parser.html" title="Struct template no_case_parser">no_case_parser</a></code>.
      </p>
<h5>
<a name="boost_parser.tutorial.directives.h8"></a>
        <span class="phrase"><a name="boost_parser.tutorial.directives._globalname_alt__boost__parser__lexeme___code__phrase_role__identifier__lexeme__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.directives._globalname_alt__boost__parser__lexeme___code__phrase_role__identifier__lexeme__phrase__phrase_role__special______phrase___code___globalname_">lexeme[]</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc4518d7b420ac61d70ea3405ec74fd.html" title="Global lexeme">lexeme</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>
        disables use of the skipper, if a skipper is being used, within the parse
        of <code class="computeroutput"><span class="identifier">p</span></code>. This is useful, for
        instance, if you want to enable skipping in most parts of your parser, but
        disable it only in one section where it doesn't belong. If you are skipping
        whitespace in most of your parser, but want to parse strings that may contain
        spaces, you should use <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc4518d7b420ac61d70ea3405ec74fd.html" title="Global lexeme">lexeme[]</a></code>:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">string_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="char">'"'</span><span class="special">];</span>
</pre>
<p>
        Without <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc4518d7b420ac61d70ea3405ec74fd.html" title="Global lexeme">lexeme[]</a></code>, our string parser would correctly
        match <code class="computeroutput"><span class="string">"foo bar"</span></code>, but
        the generated attribute would be <code class="computeroutput"><span class="string">"foobar"</span></code>.
      </p>
<p>
        Creates a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1lexeme__parser.html" title="Struct template lexeme_parser">lexeme_parser</a></code>.
      </p>
<h5>
<a name="boost_parser.tutorial.directives.h9"></a>
        <span class="phrase"><a name="boost_parser.tutorial.directives._globalname_alt__boost__parser__skip___code__phrase_role__identifier__skip__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.directives._globalname_alt__boost__parser__skip___code__phrase_role__identifier__skip__phrase__phrase_role__special______phrase___code___globalname_">skip[]</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad895ab5096656bb778ec77ae04834654.html" title="Global skip">skip[]</a></code> is like the inverse of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc4518d7b420ac61d70ea3405ec74fd.html" title="Global lexeme">lexeme[]</a></code>. It enables skipping in the
        parse, even if it was not enabled before. For example, within a call to
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> that uses a skipper, let's
        say we have these parsers in use:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">one_or_more</span> <span class="special">=</span> <span class="special">+</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">skip_or_skip_not_there_is_no_try</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">[</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">skip</span><span class="special">[</span><span class="identifier">one_or_more</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="identifier">one_or_more</span><span class="special">];</span>
</pre>
<p>
        The use of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc4518d7b420ac61d70ea3405ec74fd.html" title="Global lexeme">lexeme[]</a></code> disables skipping, but then
        the use of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad895ab5096656bb778ec77ae04834654.html" title="Global skip">skip[]</a></code> turns it back on. The net
        result is that the first occurrence of <code class="computeroutput"><span class="identifier">one_or_more</span></code>
        will use the skipper passed to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>;
        the second will not.
      </p>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad895ab5096656bb778ec77ae04834654.html" title="Global skip">skip[]</a></code> has another use. You can parameterize
        skip with a different parser to change the skipper just within the scope
        of the directive. Let's say we passed <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a13a98612c59d598c30d400ff92c7765f.html" title="Global ws">ws</a></code> to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>,
        and we're using these parsers somewhere within that <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        call:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">zero_or_more</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">skip_both_ways</span> <span class="special">=</span> <span class="identifier">zero_or_more</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">skip</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">blank</span><span class="special">)[</span><span class="identifier">zero_or_more</span><span class="special">];</span>
</pre>
<p>
        The first occurrence of <code class="computeroutput"><span class="identifier">zero_or_more</span></code>
        will use the skipper passed to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>,
        which is <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a13a98612c59d598c30d400ff92c7765f.html" title="Global ws">ws</a></code>;
        the second will use <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6b2b76f815ee8ea0b5c027335a21b31e.html" title="Global blank">blank</a></code> as its skipper.
      </p>
<p>
        Creates a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1skip__parser.html" title="Struct template skip_parser">skip_parser</a></code>.
      </p>
<h5>
<a name="boost_parser.tutorial.directives.h10"></a>
        <span class="phrase"><a name="boost_parser.tutorial.directives._globalname_alt__boost__parser__merge___code__phrase_role__identifier__merge__phrase__phrase_role__special______phrase___code___globalname____globalname_alt__boost__parser__separate___code__phrase_role__identifier__separate__phrase__phrase_role__special______phrase___code___globalname___and__globalname_alt__boost__parser__transform___code__phrase_role__identifier__transform__phrase__phrase_role__special_____phrase__phrase_role__identifier__f__phrase__phrase_role__special_______phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.directives._globalname_alt__boost__parser__merge___code__phrase_role__identifier__merge__phrase__phrase_role__special______phrase___code___globalname____globalname_alt__boost__parser__separate___code__phrase_role__identifier__separate__phrase__phrase_role__special______phrase___code___globalname___and__globalname_alt__boost__parser__transform___code__phrase_role__identifier__transform__phrase__phrase_role__special_____phrase__phrase_role__identifier__f__phrase__phrase_role__special_______phrase___code___globalname_">merge[], separate[],
        and <code class="computeroutput">transform(f)[]</code></a>
      </h5>
<p>
        These directives influence the generation of attributes. See <a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation" title="Attribute Generation">Attribute
        Generation</a> section for more details on them.
      </p>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a11728b9935b826cf6a066766b347f17b.html" title="Global merge">merge[]</a></code> and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a1c4c5ec9144e8f4d1e1e1cb848a0ae04.html" title="Global separate">separate[]</a></code>
        create a copy of the given <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1seq__parser.html" title="Struct template seq_parser">seq_parser</a></code>.
      </p>
<p>
        <code class="computeroutput">transform(f)[]</code>
        creates a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1transform__parser.html" title="Struct template transform_parser">tranform_parser</a></code>.
      </p>
<h5>
<a name="boost_parser.tutorial.directives.h11"></a>
        <span class="phrase"><a name="boost_parser.tutorial.directives._globalname_alt__boost__parser__delimiter___code__phrase_role__identifier__delimiter__phrase__phrase_role__special_____phrase__phrase_role__identifier__p__phrase__phrase_role__special_______phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.directives._globalname_alt__boost__parser__delimiter___code__phrase_role__identifier__delimiter__phrase__phrase_role__special_____phrase__phrase_role__identifier__p__phrase__phrase_role__special_______phrase___code___globalname_"><code class="computeroutput">delimiter(p)[]</code></a>
      </h5>
<p>
        The <code class="computeroutput">delimiter</code>
        directive enables the use of a delimiter within a permutation parser. It
        <span class="bold"><strong>only</strong></span> applies to permutation parsers, just
        as <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a11728b9935b826cf6a066766b347f17b.html" title="Global merge">merge[]</a></code> and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a1c4c5ec9144e8f4d1e1e1cb848a0ae04.html" title="Global separate">separate[]</a></code>
        only apply to sequence parsers. Consider this permutation parser.
      </p>
<pre class="programlisting"><span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">||</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="string">"foo"</span><span class="special">)</span> <span class="special">||</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'g'</span><span class="special">);</span>
</pre>
<p>
        This will match all of: an integer, <code class="computeroutput"><span class="string">"foo"</span></code>,
        and <code class="computeroutput"><span class="char">'g'</span></code>, in any order (for example,
        <code class="computeroutput"><span class="string">"foo g 42"</span></code>). If you
        also want for those three elements to be delimited by commas, you could write
        this parser instead.
      </p>
<pre class="programlisting"><span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">delimited_parser</span> <span class="special">=</span>
    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">delimiter</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="char">','</span><span class="special">))[</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">||</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="string">"foo"</span><span class="special">)</span> <span class="special">||</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'g'</span><span class="special">)];</span>
</pre>
<p>
        <code class="computeroutput"><span class="identifier">delimited_parser</span></code> will parse
        the same elements as <code class="computeroutput"><span class="identifier">parser</span></code>,
        but will also require commas between the elements (as in <code class="computeroutput"><span class="string">"foo,
        g, 42"</span></code>).
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.combining_operations"></a><a class="link" href="tutorial.html#boost_parser.tutorial.combining_operations" title="Combining Operations">Combining
      Operations</a>
</h3></div></div></div>
<p>
        Certain overloaded operators are defined for all parsers in Boost.Parser.
        We've already seen some of them used in this tutorial, especially <code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;&gt;</span></code>,
        <code class="computeroutput"><span class="keyword">operator</span><span class="special">|</span></code>,
        and <code class="computeroutput"><span class="keyword">operator</span><span class="special">||</span></code>,
        which are used to form sequence parsers, alternative parsers, and permutation
        parsers, respectively.
      </p>
<p>
        Here are all the operator overloaded for parsers. In the tables below:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            <code class="computeroutput"><span class="identifier">c</span></code> is a character of type
            <code class="computeroutput"><span class="keyword">char</span></code> or <code class="computeroutput"><span class="keyword">char32_t</span></code>;
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">a</span></code> is a semantic action;
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">r</span></code> is an object whose
            type models <code class="computeroutput"><span class="identifier">parsable_range</span></code>
            (see <a class="link" href="concepts.html" title="Concepts">Concepts</a>); and
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">p</span></code>, <code class="computeroutput"><span class="identifier">p1</span></code>,
            <code class="computeroutput"><span class="identifier">p2</span></code>, ... are parsers.
          </li>
</ul></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          Some of the expressions in this table consume no input. All parsers consume
          the input they match unless otherwise stated in the table below.
        </p></td></tr>
</table></div>
<div class="table">
<a name="boost_parser.tutorial.combining_operations.t0"></a><p class="title"><b>Table 25.7. Combining Operations and Their Semantics</b></p>
<div class="table-contents"><table class="table" summary="Combining Operations and Their Semantics">
<colgroup>
<col>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th>
                <p>
                  Expression
                </p>
              </th>
<th>
                <p>
                  Semantics
                </p>
              </th>
<th>
                <p>
                  Attribute Type
                </p>
              </th>
<th>
                <p>
                  Notes
                </p>
              </th>
</tr></thead>
<tbody>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">!</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches iff <code class="computeroutput"><span class="identifier">p</span></code> does
                  not match; consumes no input.
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches iff <code class="computeroutput"><span class="identifier">p</span></code> matches;
                  consumes no input.
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">*</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  Parses using <code class="computeroutput"><span class="identifier">p</span></code>
                  repeatedly until <code class="computeroutput"><span class="identifier">p</span></code>
                  no longer matches; always matches.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
<td>
                <p>
                  Matching <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                  an unlimited number of times creates an infinite loop, which is
                  undefined behavior in C++. Boost.Parser will assert in debug mode
                  when it encounters <code class="computeroutput"><span class="special">*</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                  (this applies to unconditional <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code> only).
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">+</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  Parses using <code class="computeroutput"><span class="identifier">p</span></code>
                  repeatedly until <code class="computeroutput"><span class="identifier">p</span></code>
                  no longer matches; matches iff <code class="computeroutput"><span class="identifier">p</span></code>
                  matches at least once.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
<td>
                <p>
                  Matching <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                  an unlimited number of times creates an infinite loop, which is
                  undefined behavior in C++. Boost.Parser will assert in debug mode
                  when it encounters <code class="computeroutput"><span class="special">+</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                  (this applies to unconditional <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code> only).
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">-</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><span class="identifier">p</span> <span class="special">|</span> <a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;&gt;</span>
                  <span class="identifier">p2</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches iff <code class="computeroutput"><span class="identifier">p1</span></code>
                  matches and then <code class="computeroutput"><span class="identifier">p2</span></code>
                  matches.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">)&gt;</span></code> (See note.)
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="special">&gt;&gt;</span></code> is associative;
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;&gt;</span>
                  <span class="identifier">p2</span> <span class="special">&gt;&gt;</span>
                  <span class="identifier">p3</span></code>, <code class="computeroutput"><span class="special">(</span><span class="identifier">p1</span> <span class="special">&gt;&gt;</span>
                  <span class="identifier">p2</span><span class="special">)</span>
                  <span class="special">&gt;&gt;</span> <span class="identifier">p3</span></code>,
                  and <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;&gt;</span>
                  <span class="special">(</span><span class="identifier">p2</span>
                  <span class="special">&gt;&gt;</span> <span class="identifier">p3</span><span class="special">)</span></code> are all equivalent. This attribute
                  type only applies to the case where <code class="computeroutput"><span class="identifier">p1</span></code>
                  and <code class="computeroutput"><span class="identifier">p2</span></code> both generate
                  attributes; see <a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation" title="Attribute Generation">Attribute
                  Generation</a> for the full rules. Differs in precedence from
                  <code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;</span></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">&gt;&gt;</span>
                  <span class="identifier">c</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><span class="identifier">p</span> <span class="special">&gt;&gt;</span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">c</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">&gt;&gt;</span>
                  <span class="identifier">r</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><span class="identifier">p</span> <span class="special">&gt;&gt;</span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">r</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;</span>
                  <span class="identifier">p2</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches iff <code class="computeroutput"><span class="identifier">p1</span></code>
                  matches and then <code class="computeroutput"><span class="identifier">p2</span></code>
                  matches. No back-tracking is allowed after <code class="computeroutput"><span class="identifier">p1</span></code>
                  matches; if <code class="computeroutput"><span class="identifier">p1</span></code>
                  matches but then <code class="computeroutput"><span class="identifier">p2</span></code>
                  does not, the top-level parse fails.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">)&gt;</span></code> (See note.)
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="special">&gt;</span></code> is associative;
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;</span>
                  <span class="identifier">p2</span> <span class="special">&gt;</span>
                  <span class="identifier">p3</span></code>, <code class="computeroutput"><span class="special">(</span><span class="identifier">p1</span> <span class="special">&gt;</span>
                  <span class="identifier">p2</span><span class="special">)</span>
                  <span class="special">&gt;</span> <span class="identifier">p3</span></code>,
                  and <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;</span>
                  <span class="special">(</span><span class="identifier">p2</span>
                  <span class="special">&gt;</span> <span class="identifier">p3</span><span class="special">)</span></code> are all equivalent. This attribute
                  type only applies to the case where <code class="computeroutput"><span class="identifier">p1</span></code>
                  and <code class="computeroutput"><span class="identifier">p2</span></code> both generate
                  attributes; see <a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation" title="Attribute Generation">Attribute
                  Generation</a> for the full rules. Differs in precedence from
                  <code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;&gt;</span></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">&gt;</span>
                  <span class="identifier">c</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><span class="identifier">p</span> <span class="special">&gt;</span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">c</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">&gt;</span>
                  <span class="identifier">r</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><span class="identifier">p</span> <span class="special">&gt;</span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">r</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">|</span>
                  <span class="identifier">p2</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches iff either <code class="computeroutput"><span class="identifier">p1</span></code>
                  matches or <code class="computeroutput"><span class="identifier">p2</span></code> matches.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">)&gt;</span></code> (See note.)
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="special">|</span></code> is associative;
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">|</span>
                  <span class="identifier">p2</span> <span class="special">|</span>
                  <span class="identifier">p3</span></code>, <code class="computeroutput"><span class="special">(</span><span class="identifier">p1</span> <span class="special">|</span>
                  <span class="identifier">p2</span><span class="special">)</span>
                  <span class="special">|</span> <span class="identifier">p3</span></code>,
                  and <code class="computeroutput"><span class="identifier">p1</span> <span class="special">|</span>
                  <span class="special">(</span><span class="identifier">p2</span>
                  <span class="special">|</span> <span class="identifier">p3</span><span class="special">)</span></code> are all equivalent. This attribute
                  type only applies to the case where <code class="computeroutput"><span class="identifier">p1</span></code>
                  and <code class="computeroutput"><span class="identifier">p2</span></code> both generate
                  attributes, and where the attribute types are different; see <a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation" title="Attribute Generation">Attribute
                  Generation</a> for the full rules.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">|</span>
                  <span class="identifier">c</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><span class="identifier">p</span> <span class="special">|</span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">c</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">|</span>
                  <span class="identifier">r</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><span class="identifier">p</span> <span class="special">|</span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">r</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">||</span>
                  <span class="identifier">p2</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches iff <code class="computeroutput"><span class="identifier">p1</span></code>
                  matches and <code class="computeroutput"><span class="identifier">p2</span></code>
                  matches, regardless of the order they match in.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">)&gt;</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="special">||</span></code> is associative;
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">||</span>
                  <span class="identifier">p2</span> <span class="special">||</span>
                  <span class="identifier">p3</span></code>, <code class="computeroutput"><span class="special">(</span><span class="identifier">p1</span> <span class="special">||</span>
                  <span class="identifier">p2</span><span class="special">)</span>
                  <span class="special">||</span> <span class="identifier">p3</span></code>,
                  and <code class="computeroutput"><span class="identifier">p1</span> <span class="special">||</span>
                  <span class="special">(</span><span class="identifier">p2</span>
                  <span class="special">||</span> <span class="identifier">p3</span><span class="special">)</span></code> are all equivalent. It is an error
                  to include a <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code> (conditional
                  or non-conditional) in an <code class="computeroutput"><span class="keyword">operator</span><span class="special">||</span></code> expression. Though the parsers
                  are matched in any order, the attribute elements are always in
                  the order written in the <code class="computeroutput"><span class="keyword">operator</span><span class="special">||</span></code> expression.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">-</span>
                  <span class="identifier">p2</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><span class="special">!</span><span class="identifier">p2</span>
                  <span class="special">&gt;&gt;</span> <span class="identifier">p1</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">)</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">-</span>
                  <span class="identifier">c</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><span class="identifier">p</span> <span class="special">-</span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">c</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">-</span>
                  <span class="identifier">r</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><span class="identifier">p</span> <span class="special">-</span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">r</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">%</span>
                  <span class="identifier">p2</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="identifier">p2</span> <span class="special">&gt;&gt;</span>
                  <span class="identifier">p1</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">)&gt;</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">%</span>
                  <span class="identifier">c</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><span class="identifier">p</span> <span class="special">%</span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">c</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">%</span>
                  <span class="identifier">r</span></code>
                </p>
              </td>
<td>
                <p>
                  Equivalent to <code class="computeroutput"><span class="identifier">p</span> <span class="special">%</span> <span class="identifier">lit</span><span class="special">(</span><span class="identifier">r</span><span class="special">)</span></code>.
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span><span class="special">[</span><span class="identifier">a</span><span class="special">]</span></code>
                </p>
              </td>
<td>
                <p>
                  Matches iff <code class="computeroutput"><span class="identifier">p</span></code> matches.
                  If <code class="computeroutput"><span class="identifier">p</span></code> matches, the
                  semantic action <code class="computeroutput"><span class="identifier">a</span></code>
                  is executed.
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
              </td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          All the character parsers, like <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a3d982dd5003327f579e689e9fbbf7cb4.html" title="Global cp">cp</a></code> and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1adf23d22a6b9aa56e8e5d5c5bc2e97881.html" title="Global cu">cu</a></code> produce either <code class="computeroutput"><span class="keyword">char</span></code> or <code class="computeroutput"><span class="keyword">char32_t</span></code>
          attributes. So when you see "<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
          if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is
          <code class="computeroutput"><span class="keyword">char</span></code> or <code class="computeroutput"><span class="keyword">char32_t</span></code>,
          otherwise <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>"
          in the table above, that effectively means that every sequences of character
          attributes get turned into a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
          The only time this does not happen is when you introduce your own rules
          with attributes using another character type (or use <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1attribute.html" title="Struct template attribute">attribute</a></code> to do so).
        </p></td></tr>
</table></div>
<p>
        There are a couple of special rules not captured in the table above:
      </p>
<p>
        First, the zero-or-more and one-or-more repetitions (<code class="computeroutput"><span class="keyword">operator</span><span class="special">*()</span></code> and <code class="computeroutput"><span class="keyword">operator</span><span class="special">+()</span></code>, respectively) may collapse when combined.
        For any parser <code class="computeroutput"><span class="identifier">p</span></code>, <code class="computeroutput"><span class="special">+(+</span><span class="identifier">p</span><span class="special">)</span></code>
        collapses to <code class="computeroutput"><span class="special">+</span><span class="identifier">p</span></code>;
        <code class="computeroutput"><span class="special">**</span><span class="identifier">p</span></code>,
        <code class="computeroutput"><span class="special">*+</span><span class="identifier">p</span></code>,
        and <code class="computeroutput"><span class="special">+*</span><span class="identifier">p</span></code>
        each collapse to just <code class="computeroutput"><span class="special">*</span><span class="identifier">p</span></code>.
      </p>
<p>
        Second, using <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
        in an alternative parser as any alternative <span class="bold"><strong>except</strong></span>
        the last one is a common source of errors; Boost.Parser disallows it. This
        is true because, for any parser <code class="computeroutput"><span class="identifier">p</span></code>,
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a>
        <span class="special">|</span> <span class="identifier">p</span></code>
        is equivalent to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>,
        since <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
        always matches. This is not true for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code> parameterized with a condition.
        For any condition <code class="computeroutput"><span class="identifier">cond</span></code>,
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a><span class="special">(</span><span class="identifier">cond</span><span class="special">)</span></code>
        is allowed to appear anywhere within an alternative parser.
      </p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          The C++ operators <code class="computeroutput"><span class="special">&gt;</span></code> and
          <code class="computeroutput"><span class="special">&gt;&gt;</span></code> have different precedences.
          This will sometimes come up in warnings from your compiler. No matter how
          you do or do not parenthesize chains of parsers separated by <code class="computeroutput"><span class="special">&gt;</span></code> and <code class="computeroutput"><span class="special">&gt;&gt;</span></code>,
          the resulting expression evaluates the same. Feel free to add parentheses
          if your compiler complains. More broadly, keep the C++ operator precedence
          rules in mind when writing your parsers — the simplest thing to
          write may not have your intended semantics.
        </p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          When looking at Boost.Parser parsers in a debugger, or when looking at
          their reference documentation, you may see reference to the template <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1parser__interface.html" title="Struct template parser_interface">parser_interface</a></code>.
          This template exists to provide the operator overloads described above.
          It allows the parsers themselves to be very simple — most parsers
          are just a struct with two member functions. <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1parser__interface.html" title="Struct template parser_interface">parser_interface</a></code> is essentially
          invisible when using Boost.Parser, and you should never have to name this
          template in your own code.
        </p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.attribute_generation"></a><a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation" title="Attribute Generation">Attribute
      Generation</a>
</h3></div></div></div>
<p>
        So far, we've seen several different types of attributes that come from different
        parsers, <code class="computeroutput"><span class="keyword">int</span></code> for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aebfca0484fcebac2789c946c6a93b116.html" title="Global int_">int_</a></code>,
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span>
        <span class="keyword">int</span><span class="special">&gt;</span></code>
        for <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">&gt;&gt;</span>
        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">int_</span></code>, etc. Let's get into how this works
        with more rigor.
      </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          Some parsers have no attribute at all. In the tables below, the type of
          the attribute is listed as "None." There is a non-<code class="computeroutput"><span class="keyword">void</span></code> type that is returned from each parser
          that lacks an attribute. This keeps the logic simple; having to handle
          the two cases — <code class="computeroutput"><span class="keyword">void</span></code>
          or non-<code class="computeroutput"><span class="keyword">void</span></code> — would
          make the library significantly more complicated. The type of this non-<code class="computeroutput"><span class="keyword">void</span></code> attribute associated with these parsers
          is an implementation detail. The type comes from the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">detail</span></code>
          namespace and is pretty useless. You should never see this type in practice.
          Within semantic actions, asking for the attribute of a non-attribute-producing
          parser (using <code class="computeroutput"><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>)
          will yield a value of the special type <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">none</span></code>.
          When calling <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> in a form that returns
          the attribute parsed, when there is no attribute, simply returns <code class="computeroutput"><span class="keyword">bool</span></code>; this indicates the success of failure
          of the parse.
        </p></td></tr>
</table></div>
<div class="warning"><table border="0" summary="Warning">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../doc/src/images/warning.png"></td>
<th align="left">Warning</th>
</tr>
<tr><td align="left" valign="top"><p>
          Boost.Parser assumes that all attributes are semi-regular (see <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">semiregular</span></code>). Within the Boost.Parser
          code, attributes are assigned, moved, copy, and default constructed. There
          is no support for move-only or non-default-constructible types.
        </p></td></tr>
</table></div>
<h5>
<a name="boost_parser.tutorial.attribute_generation.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.attribute_generation.the_attribute_type_trait___classname_alt__boost__parser__attribute___code__phrase_role__identifier__attribute__phrase___code___classname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation.the_attribute_type_trait___classname_alt__boost__parser__attribute___code__phrase_role__identifier__attribute__phrase___code___classname_">The
        attribute type trait, attribute</a>
      </h5>
<p>
        You can use <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1attribute.html" title="Struct template attribute">attribute</a></code>
        (and the associated alias, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1acab73b5438b6bab7862f0409c6845b50.html" title="Type definition attribute_t">attribute_t</a></code>) to determine the
        attribute a parser would have if it were passed to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>.
        Since at least one parser (<code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>) has a polymorphic attribute
        type, <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1attribute.html" title="Struct template attribute">attribute</a></code>
        also takes the type of the range being parsed. If a parser produces no attribute,
        <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1attribute.html" title="Struct template attribute">attribute</a></code>
        will produce <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1none.html" title="Struct none">none</a></code>,
        not <code class="computeroutput"><span class="keyword">void</span></code>.
      </p>
<p>
        If you want to feed an iterator/sentinel pair to <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1attribute.html" title="Struct template attribute">attribute</a></code>, create a range from
        it like so:
      </p>
<pre class="programlisting"><span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="comment">/* ... */</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">first</span> <span class="special">=</span> <span class="comment">/* ... */</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">last</span> <span class="special">=</span> <span class="comment">/* ... */</span><span class="special">;</span>

<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="comment">// You can of course use std::ranges::subrange directly in C++20 and later.</span>
<span class="keyword">using</span> <span class="identifier">attr_type</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">attribute_t</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">BOOST_PARSER_SUBRANGE</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">)),</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">parser</span><span class="special">)&gt;;</span>
</pre>
<p>
        There is no single attribute type for any parser, since a parser can be placed
        within <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aba924d9dafe70d651680058e6004f31e.html" title="Global omit">omit[]</a></code>, which makes its attribute
        type <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1none.html" title="Struct none">none</a></code>.
        Therefore, <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1attribute.html" title="Struct template attribute">attribute</a></code>
        cannot tell you what attribute your parser will produce under all circumstances;
        it only tells you what it would produce if it were passed to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>.
      </p>
<h5>
<a name="boost_parser.tutorial.attribute_generation.h1"></a>
        <span class="phrase"><a name="boost_parser.tutorial.attribute_generation.parser_attributes"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation.parser_attributes">Parser
        attributes</a>
      </h5>
<p>
        This table summarizes the attributes generated for all Boost.Parser parsers.
        In the table below:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            <span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><code class="computeroutput"><span class="special">()</span></code>
            is a notional macro that expands to the resolution of parse argument
            or evaluation of a parse predicate (see <a class="link" href="tutorial.html#boost_parser.tutorial.the_parsers_and_their_uses" title="The Parsers And Their Uses">The
            Parsers And Their Uses</a>); and
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">x</span></code> and <code class="computeroutput"><span class="identifier">y</span></code>
            represent arbitrary objects.
          </li>
</ul></div>
<div class="table">
<a name="boost_parser.tutorial.attribute_generation.t0"></a><p class="title"><b>Table 25.8. Parsers and Their Attributes</b></p>
<div class="table-contents"><table class="table" summary="Parsers and Their Attributes">
<colgroup>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th>
                <p>
                  Parser
                </p>
              </th>
<th>
                <p>
                  Attribute Type
                </p>
              </th>
<th>
                <p>
                  Notes
                </p>
              </th>
</tr></thead>
<tbody>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a15e2b8331566a0b97dad680ac4855004.html" title="Global eol">eol</a></code>
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aeba0f48cb171e5e5f121d8ed274a43d5.html" title="Global eoi">eoi</a></code>
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a18903d5e72b8a429e91152e4e57c6e68.html" title="Function template attr">attr</a><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">decltype</span><span class="special">(</span><span class="emphasis"><em><code class="literal">RESOLVE</code></em></span><span class="special">(</span><span class="identifier">x</span><span class="special">))</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>
                </p>
              </td>
<td>
                <p>
                  The code point type in Unicode parsing, or <code class="computeroutput"><span class="keyword">char</span></code>
                  in non-Unicode parsing; see below.
                </p>
              </td>
<td>
                <p>
                  Includes all the <code class="computeroutput"><span class="identifier">_p</span></code>
                  <a href="https://en.cppreference.com/w/cpp/language/user_literal" target="_top">UDLs</a>
                  that take a single character, and all character class parsers like
                  <code class="computeroutput"><span class="identifier">control</span></code> and <code class="computeroutput"><span class="identifier">lower</span></code>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a3d982dd5003327f579e689e9fbbf7cb4.html" title="Global cp">cp</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">char32_t</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1adf23d22a6b9aa56e8e5d5c5bc2e97881.html" title="Global cu">cu</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">char</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa8c123b0cbde389f5d5eaf353169ef09.html" title="Function lit">lit</a><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
<td>
                <p>
                  Includes all the <code class="computeroutput"><span class="identifier">_l</span></code>
                  <a href="https://en.cppreference.com/w/cpp/language/user_literal" target="_top">UDLs</a>.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7e079d756d52cf5fc94cbdca53bb8b4f.html" title="Function template string">string</a><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
                </p>
              </td>
<td>
                <p>
                  Includes all the <code class="computeroutput"><span class="identifier">_p</span></code>
                  <a href="https://en.cppreference.com/w/cpp/language/user_literal" target="_top">UDLs</a>
                  that take a string.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab79cf11acb9757d1e82abbc6ac31bf51.html" title="Global bool_">bool_</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">bool</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abbe29c0334264fd28535b8a3abec39e2.html" title="Global bin">bin</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">int</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab1dbbcfeb807e261ffaaf0224e21f7ca.html" title="Global oct">oct</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">int</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1af7c7911157c8d43d4328ec6342a77a31.html" title="Global hex">hex</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">int</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a591f036e613e107e00e5136226c02ec8.html" title="Global ushort_">ushort_</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">short</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a7399c57e54ceedc43f5978ac51618a.html" title="Global uint_">uint_</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">int</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6225883e4382da031c727b333a585f58.html" title="Global ulong_">ulong_</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">long</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ac1d1fef19c32c6b74cdc3857ffa9feb8.html" title="Global ulong_long">ulong_long</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">unsigned</span> <span class="keyword">long</span>
                  <span class="keyword">long</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ac1331c03e89ff310052d9a38bc75621c.html" title="Global short_">short_</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">short</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aebfca0484fcebac2789c946c6a93b116.html" title="Global int_">int_</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">int</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1afdbc039990e44df91b04ef713b6d6058.html" title="Global long_">long_</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">long</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a85f44231c5106a739257b24a2b6a40ff.html" title="Global long_long">long_long</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">long</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2c6a3d18060166bd926f3150327819a4.html" title="Global float_">float_</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">float</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a6e37283853b49605ec05b4a1969eaaac.html" title="Global double_">double_</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="keyword">double</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols&lt;T&gt;</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">T</span></code>
                </p>
              </td>
<td>
              </td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>
        is a bit odd, since its attribute type is polymorphic. When you use <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>
        to parse text in the non-Unicode code path (i.e. a string of <code class="computeroutput"><span class="keyword">char</span></code>), the attribute is <code class="computeroutput"><span class="keyword">char</span></code>.
        When you use the exact same <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code> to parse in the Unicode-aware
        code path, all matching is code point based, and so the attribute type is
        the type used to represent code points, <code class="computeroutput"><span class="keyword">char32_t</span></code>.
        All parsing of UTF-8 falls under this case.
      </p>
<p>
        Here, we're parsing plain <code class="computeroutput"><span class="keyword">char</span></code>s,
        meaning that the parsing is in the non-Unicode code path, the attribute of
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>
        is <code class="computeroutput"><span class="keyword">char</span></code>:
      </p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">parse</span><span class="special">(</span><span class="string">"some text"</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">char_</span><span class="special">);</span>
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same_v</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">result</span><span class="special">),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;&gt;));</span>
</pre>
<p>
        When you parse UTF-8, the matching is done on a code point basis, so the
        attribute type is <code class="computeroutput"><span class="keyword">char32_t</span></code>:
      </p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">parse</span><span class="special">(</span><span class="string">"some text"</span> <span class="special">|</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">as_utf8</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">char_</span><span class="special">);</span>
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same_v</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">result</span><span class="special">),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">char32_t</span><span class="special">&gt;&gt;));</span>
</pre>
<p>
        The good news is that usually you don't parse characters individually. When
        you parse with <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>,
        you usually parse repetition of then, which will produce a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>,
        regardless of whether you're in Unicode parsing mode or not. If you do need
        to parse individual characters, and want to lock down their attribute type,
        you can use <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a3d982dd5003327f579e689e9fbbf7cb4.html" title="Global cp">cp</a></code>
        and/or <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1adf23d22a6b9aa56e8e5d5c5bc2e97881.html" title="Global cu">cu</a></code>
        to enforce a non-polymorphic attribute type.
      </p>
<h5>
<a name="boost_parser.tutorial.attribute_generation.h2"></a>
        <span class="phrase"><a name="boost_parser.tutorial.attribute_generation.combining_operation_attributes"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation.combining_operation_attributes">Combining
        operation attributes</a>
      </h5>
<p>
        Combining operations of course affect the generation of attributes. In the
        tables below:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            <code class="computeroutput"><span class="identifier">m</span></code> and <code class="computeroutput"><span class="identifier">n</span></code>
            are parse arguments that resolve to integral values;
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">pred</span></code> is a parse predicate;
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">arg0</span></code>, <code class="computeroutput"><span class="identifier">arg1</span></code>,
            <code class="computeroutput"><span class="identifier">arg2</span></code>, ... are parse arguments;
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">a</span></code> is a semantic action;
            and
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">p</span></code>, <code class="computeroutput"><span class="identifier">p1</span></code>,
            <code class="computeroutput"><span class="identifier">p2</span></code>, ... are parsers that
            generate attributes.
          </li>
</ul></div>
<div class="table">
<a name="boost_parser.tutorial.attribute_generation.t1"></a><p class="title"><b>Table 25.9. Combining Operations and Their Attributes</b></p>
<div class="table-contents"><table class="table" summary="Combining Operations and Their Attributes">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
                <p>
                  Parser
                </p>
              </th>
<th>
                <p>
                  Attribute Type
                </p>
              </th>
</tr></thead>
<tbody>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">!</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">*</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">+</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">+*</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">*+</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">-</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;&gt;</span>
                  <span class="identifier">p2</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;</span>
                  <span class="identifier">p2</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;&gt;</span>
                  <span class="identifier">p2</span> <span class="special">&gt;&gt;</span>
                  <span class="identifier">p3</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p3</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;</span>
                  <span class="identifier">p2</span> <span class="special">&gt;&gt;</span>
                  <span class="identifier">p3</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p3</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;&gt;</span>
                  <span class="identifier">p2</span> <span class="special">&gt;</span>
                  <span class="identifier">p3</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p3</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;</span>
                  <span class="identifier">p2</span> <span class="special">&gt;</span>
                  <span class="identifier">p3</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p3</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">|</span>
                  <span class="identifier">p2</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">|</span>
                  <span class="identifier">p2</span> <span class="special">|</span>
                  <span class="identifier">p3</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p3</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">||</span>
                  <span class="identifier">p2</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">||</span>
                  <span class="identifier">p2</span> <span class="special">||</span>
                  <span class="identifier">p3</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p3</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">%</span>
                  <span class="identifier">p2</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span><span class="special">[</span><span class="identifier">a</span><span class="special">]</span></code>
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad95e37e5cf4468149eec5f774ad977f3.html" title="Function template repeat">repeat</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)[</span><span class="identifier">p</span><span class="special">]</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad95e37e5cf4468149eec5f774ad977f3.html" title="Function template repeat">repeat</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">,</span> <span class="identifier">arg1</span><span class="special">)[</span><span class="identifier">p</span><span class="special">]</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abfc7ab7877a423d66c6a8fb49a702bd5.html" title="Function template if_">if_</a><span class="special">(</span><span class="identifier">pred</span><span class="special">)[</span><span class="identifier">p</span><span class="special">]</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad0e7ed5270417b766644b5197a469e7c.html" title="Function template switch_">switch_</a><span class="special">(</span><span class="identifier">arg0</span><span class="special">)(</span><span class="identifier">arg1</span><span class="special">,</span> <span class="identifier">p1</span><span class="special">)(</span><span class="identifier">arg2</span><span class="special">,</span> <span class="identifier">p2</span><span class="special">)...</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">),</span> <span class="special">...&gt;</span></code>
                </p>
              </td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          All the character parsers, like <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a3d982dd5003327f579e689e9fbbf7cb4.html" title="Global cp">cp</a></code> and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1adf23d22a6b9aa56e8e5d5c5bc2e97881.html" title="Global cu">cu</a></code> produce either <code class="computeroutput"><span class="keyword">char</span></code> or <code class="computeroutput"><span class="keyword">char32_t</span></code>
          attributes. So when you see "<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
          if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is
          <code class="computeroutput"><span class="keyword">char</span></code> or <code class="computeroutput"><span class="keyword">char32_t</span></code>,
          otherwise <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>"
          in the table above, that effectively means that every sequences of character
          attributes get turned into a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
          The only time this does not happen is when you introduce your own rules
          with attributes using another character type (or use <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1attribute.html" title="Struct template attribute">attribute</a></code> to do so).
        </p></td></tr>
</table></div>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          In case you did not notice it above, adding a semantic action to a parser
          erases the parser's attribute. The attribute is still available inside
          the semantic action as <code class="computeroutput"><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>.
        </p></td></tr>
</table></div>
<p>
        There are a relatively small number of rules that define how sequence parsers
        and alternative parsers' attributes are generated. (Don't worry, there are
        examples below.)
      </p>
<h5>
<a name="boost_parser.tutorial.attribute_generation.h3"></a>
        <span class="phrase"><a name="boost_parser.tutorial.attribute_generation.sequence_parser_attribute_rules"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation.sequence_parser_attribute_rules">Sequence
        parser attribute rules</a>
      </h5>
<p>
        The attribute generation behavior of sequence parsers is conceptually pretty
        simple:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            the attributes of subparsers form a tuple of values;
          </li>
<li class="listitem">
            subparsers that do not generate attributes do not contribute to the sequence's
            attribute;
          </li>
<li class="listitem">
            subparsers that do generate attributes usually contribute an individual
            element to the tuple result; except
          </li>
<li class="listitem">
            when containers of the same element type are next to each other, or individual
            elements are next to containers of their type, the two adjacent attributes
            collapse into one attribute; and
          </li>
<li class="listitem">
            if the result of all that is a degenerate tuple <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
            (even if <code class="computeroutput"><span class="identifier">T</span></code> is a type
            that means "no attribute"), the attribute becomes <code class="computeroutput"><span class="identifier">T</span></code>.
          </li>
</ul></div>
<p>
        More formally, the attribute generation algorithm works like this. For a
        sequence parser <code class="computeroutput"><span class="identifier">p</span></code>, let the
        list of attribute types for the subparsers of <code class="computeroutput"><span class="identifier">p</span></code>
        be <code class="computeroutput"><span class="identifier">a0</span><span class="special">,</span>
        <span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">,</span> <span class="special">...,</span>
        <span class="identifier">an</span></code>.
      </p>
<p>
        We get the attribute of <code class="computeroutput"><span class="identifier">p</span></code>
        by evaluating a compile-time left fold operation, <code class="computeroutput"><span class="identifier">left</span><span class="special">-</span><span class="identifier">fold</span><span class="special">({</span><span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">an</span><span class="special">},</span> <span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">a0</span><span class="special">&gt;,</span> <span class="identifier">OP</span><span class="special">)</span></code>. <code class="computeroutput"><span class="identifier">OP</span></code>
        is the combining operation that takes the current attribute type (initially
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="identifier">a0</span><span class="special">&gt;</span></code>) and the next attribute type, and returns
        the new current attribute type. The current attribute type at the end of
        the fold operation is the attribute type for <code class="computeroutput"><span class="identifier">p</span></code>.
      </p>
<p>
        <code class="computeroutput"><span class="identifier">OP</span></code> attempts to apply a series
        of rules, one at a time. The rules are noted as <code class="computeroutput"><span class="identifier">X</span>
        <span class="special">&gt;&gt;</span> <span class="identifier">Y</span>
        <span class="special">-&gt;</span> <span class="identifier">Z</span></code>,
        where <code class="computeroutput"><span class="identifier">X</span></code> is the type of the
        current attribute, <code class="computeroutput"><span class="identifier">Y</span></code> is the
        type of the next attribute, and <code class="computeroutput"><span class="identifier">Z</span></code>
        is the new current attribute type. In these rules, <code class="computeroutput"><span class="identifier">C</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
        is a container of <code class="computeroutput"><span class="identifier">T</span></code>; <code class="computeroutput"><span class="identifier">none</span></code> is a special type that indicates that
        there is no attribute; <code class="computeroutput"><span class="identifier">T</span></code>
        is a type; <code class="computeroutput"><span class="identifier">CHAR</span></code> is a character
        type, either <code class="computeroutput"><span class="keyword">char</span></code> or <code class="computeroutput"><span class="keyword">char32_t</span></code>; and <code class="computeroutput"><span class="identifier">Ts</span><span class="special">...</span></code> is a parameter pack of one or more types.
        Note that <code class="computeroutput"><span class="identifier">T</span></code> may be the special
        type <code class="computeroutput"><span class="identifier">none</span></code>. The current attribute
        is always a tuple (call it <code class="computeroutput"><span class="identifier">Tup</span></code>),
        so the "current attribute <code class="computeroutput"><span class="identifier">X</span></code>"
        refers to the last element of <code class="computeroutput"><span class="identifier">Tup</span></code>,
        not <code class="computeroutput"><span class="identifier">Tup</span></code> itself, except for
        those rules that explicitly mention <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;&gt;</span></code>
        as part of <code class="computeroutput"><span class="identifier">X</span></code>'s type.
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            <code class="computeroutput"><span class="identifier">none</span> <span class="special">&gt;&gt;</span>
            <span class="identifier">T</span> <span class="special">-&gt;</span>
            <span class="identifier">T</span></code>
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">CHAR</span></code> &gt;&gt; <code class="computeroutput"><span class="identifier">CHAR</span></code> -&gt; <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">T</span> <span class="special">&gt;&gt;</span>
            <span class="identifier">none</span> <span class="special">-&gt;</span>
            <span class="identifier">T</span></code>
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">C</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&gt;&gt;</span> <span class="identifier">T</span>
            <span class="special">-&gt;</span> <span class="identifier">C</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">T</span> <span class="special">&gt;&gt;</span>
            <span class="identifier">C</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">-&gt;</span> <span class="identifier">C</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">C</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&gt;&gt;</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">-&gt;</span> <span class="identifier">C</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&gt;&gt;</span> <span class="identifier">C</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">-&gt;</span> <span class="identifier">C</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
          </li>
<li class="listitem">
            <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="identifier">none</span><span class="special">&gt;</span> <span class="special">&gt;&gt;</span>
            <span class="identifier">T</span> <span class="special">-&gt;</span>
            <a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
          </li>
<li class="listitem">
            <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="identifier">Ts</span><span class="special">...&gt;</span> <span class="special">&gt;&gt;</span>
            <span class="identifier">T</span> <span class="special">-&gt;</span>
            <a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="identifier">Ts</span><span class="special">...,</span> <span class="identifier">T</span><span class="special">&gt;</span></code>
          </li>
</ul></div>
<p>
        The rules that combine containers with (possibly optional) adjacent values
        (e.g. <code class="computeroutput"><span class="identifier">C</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&gt;&gt;</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span>
        <span class="special">-&gt;</span> <span class="identifier">C</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>)
        have a special case for strings. If <code class="computeroutput"><span class="identifier">C</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
        is exactly <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>, and <code class="computeroutput"><span class="identifier">T</span></code>
        is either <code class="computeroutput"><span class="keyword">char</span></code> or <code class="computeroutput"><span class="keyword">char32_t</span></code>, the combination yields a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
      </p>
<p>
        Again, if the final result is that the attribute is <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>,
        the attribute becomes <code class="computeroutput"><span class="identifier">T</span></code>.
      </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top">
<p>
          What constitutes a container in the rules above is determined by the <code class="computeroutput"><span class="identifier">container</span></code> concept:
        </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">concept</span> <span class="identifier">container</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ranges</span><span class="special">::</span><span class="identifier">common_range</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&amp;&amp;</span> <span class="identifier">requires</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">)</span> <span class="special">{</span>
    <span class="special">{</span> <span class="identifier">t</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">t</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="special">*</span><span class="identifier">t</span><span class="special">.</span><span class="identifier">begin</span><span class="special">())</span> <span class="special">}</span>
        <span class="special">-&gt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">same_as</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ranges</span><span class="special">::</span><span class="identifier">iterator_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;;</span>
<span class="special">};</span>
</pre>
<p>
        </p>
</td></tr>
</table></div>
<h5>
<a name="boost_parser.tutorial.attribute_generation.h4"></a>
        <span class="phrase"><a name="boost_parser.tutorial.attribute_generation.a_sequence_parser_attribute_example"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation.a_sequence_parser_attribute_example">A
        sequence parser attribute example</a>
      </h5>
<p>
        Note that the application of <code class="computeroutput"><span class="identifier">OP</span></code>
        is done in the style of a left-fold, and is therefore greedy. This can lead
        to some non-obvious results. For example, consider this program. Thanks to
        Duncan Paterson for this very nice example!
      </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">parser</span><span class="special">/</span><span class="identifier">parser</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">print</span><span class="special">&gt;</span>

<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
  <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">id_set_action</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span>
    <span class="keyword">const</span> <span class="keyword">auto</span><span class="special">&amp;</span> <span class="special">[</span><span class="identifier">left</span><span class="special">,</span> <span class="identifier">right</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">);</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">println</span><span class="special">(</span><span class="string">"{} = {}"</span><span class="special">,</span> <span class="identifier">left</span><span class="special">,</span> <span class="identifier">right</span><span class="special">);</span>
  <span class="special">};</span>

  <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">id_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">,</span> <span class="char">'z'</span><span class="special">)</span> <span class="special">&gt;</span> <span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">,</span> <span class="char">'z'</span><span class="special">);</span>

  <span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">id_set</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">id_parser</span> <span class="special">&gt;&gt;</span> <span class="char">'='</span> <span class="special">&gt;&gt;</span> <span class="identifier">id_parser</span><span class="special">)[</span><span class="identifier">id_set_action</span><span class="special">];</span>
  <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"left=right"</span><span class="special">,</span> <span class="identifier">id_set</span><span class="special">);</span>
  <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
        Perhaps surprisingly, this program prints <code class="computeroutput"><span class="identifier">leftr</span>
        <span class="special">=</span> <span class="identifier">ight</span></code>!
        Why is this? This happens because <code class="computeroutput"><span class="identifier">id_parser</span></code>
        seems to impose structure, but does not. <code class="computeroutput"><span class="identifier">id_set</span></code>
        is exactly equivalent to this (comments added to clarify which parts are
        which below).
      </p>
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">id_set</span> <span class="special">=</span> <span class="special">(</span>
  <span class="comment">/*A*/</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">,</span> <span class="char">'z'</span><span class="special">)</span> <span class="special">&gt;</span> <span class="comment">/*B*/</span> <span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">,</span> <span class="char">'z'</span><span class="special">)</span> <span class="special">&gt;&gt;</span>
  <span class="comment">/*C*/</span> <span class="char">'='</span> <span class="special">&gt;&gt;</span>
  <span class="comment">/*D*/</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">,</span> <span class="char">'z'</span><span class="special">)</span> <span class="special">&gt;</span> <span class="comment">/*E*/</span> <span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">,</span> <span class="char">'z'</span><span class="special">)</span>
<span class="special">)[</span><span class="identifier">id_set_action</span><span class="special">];</span>
</pre>
<p>
        As Boost.Parser applies <code class="computeroutput"><span class="identifier">OP</span></code>
        to this sequence parser, the individual steps are: <code class="computeroutput"><span class="identifier">A</span></code>
        and <code class="computeroutput"><span class="identifier">B</span></code> get merged into a single
        <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>; <code class="computeroutput"><span class="identifier">C</span></code>
        is ignored, since it produces no attribute; and <code class="computeroutput"><span class="identifier">D</span></code>
        gets merged into the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
        formed earlier by <code class="computeroutput"><span class="identifier">A</span></code> and
        <code class="computeroutput"><span class="identifier">B</span></code>; finally, we have <code class="computeroutput"><span class="identifier">E</span></code>. <code class="computeroutput"><span class="identifier">E</span></code>
        does not combine with <code class="computeroutput"><span class="identifier">D</span></code>,
        as <code class="computeroutput"><span class="identifier">D</span></code> was already consumed.
        <code class="computeroutput"><span class="identifier">E</span></code> also does not combine with
        the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> we formed from <code class="computeroutput"><span class="identifier">A</span></code>,
        <code class="computeroutput"><span class="identifier">B</span></code>, and <code class="computeroutput"><span class="identifier">D</span></code>,
        since we don't combine adjacent containers. In the end, we have a 2-tuple
        of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>s, in which the first element contains
        all the characters parsed by <code class="computeroutput"><span class="identifier">A</span></code>,
        <code class="computeroutput"><span class="identifier">B</span></code>, and <code class="computeroutput"><span class="identifier">D</span></code>,
        and in which the second element contains all the characters parsed by <code class="computeroutput"><span class="identifier">E</span></code>.
      </p>
<p>
        That's clearly not what we wanted here, though. How do we get a top-level
        parser that would print <code class="computeroutput"><span class="identifier">left</span> <span class="special">=</span> <span class="identifier">right</span></code>?
        We use a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>.
        The parser used inside a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code> can never combine with
        any parser(s) outside the <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>. Instances of a rule are
        inherently separate from all parsers with which they are used, whether those
        parsers are <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>
        or non-<code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>
        parsers. So, consider a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code> equivalent to the previous
        <code class="computeroutput"><span class="identifier">id_parser</span></code> above.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">id_parser_tag</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">id_parser</span> <span class="special">=</span> <span class="string">"identifier"</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">id_parser_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">,</span> <span class="char">'z'</span><span class="special">)</span> <span class="special">&gt;</span> <span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">,</span> <span class="char">'z'</span><span class="special">);</span>
<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">id_parser</span><span class="special">);</span>
</pre>
<p>
        Later, we can use it just as we used the previous non-rule version.
      </p>
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">auto</span> <span class="identifier">id_set</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">id_parser</span> <span class="special">&gt;&gt;</span> <span class="char">'='</span> <span class="special">&gt;&gt;</span> <span class="identifier">id_parser</span><span class="special">)[</span><span class="identifier">id_set_action</span><span class="special">];</span>
</pre>
<p>
        This produces the results you might expect, since only the <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">,</span>
        <span class="char">'z'</span><span class="special">)</span> <span class="special">&gt;</span> <span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">,</span>
        <span class="char">'z'</span><span class="special">)</span></code>
        parser inside the <code class="computeroutput"><span class="identifier">id_parser</span></code>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>
        is ever eligible for combining via <code class="computeroutput"><span class="identifier">OP</span></code>.
      </p>
<h5>
<a name="boost_parser.tutorial.attribute_generation.h5"></a>
        <span class="phrase"><a name="boost_parser.tutorial.attribute_generation.alternative_parser_attribute_rules"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation.alternative_parser_attribute_rules">Alternative
        parser attribute rules</a>
      </h5>
<p>
        The rules for alternative parsers are much simpler. For an alternative parer
        <code class="computeroutput"><span class="identifier">p</span></code>, let the list of attribute
        types for the subparsers of <code class="computeroutput"><span class="identifier">p</span></code>
        be <code class="computeroutput"><span class="identifier">a0</span><span class="special">,</span>
        <span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">,</span> <span class="special">...,</span>
        <span class="identifier">an</span></code>. The attribute of <code class="computeroutput"><span class="identifier">p</span></code> is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">a0</span><span class="special">,</span> <span class="identifier">a1</span><span class="special">,</span>
        <span class="identifier">a2</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">an</span><span class="special">&gt;</span></code>, with the following steps applied:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            all the <code class="computeroutput"><span class="identifier">none</span></code> attributes
            are left out, and if any are, the attribute is wrapped in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span></code>, like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;/*...*/&gt;&gt;</span></code>;
          </li>
<li class="listitem">
            duplicates in the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span></code>
            template parameters <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">,</span> <span class="special">...</span> <span class="identifier">Tn</span><span class="special">&gt;</span></code> are removed; every type that appears
            does so exacly once;
          </li>
<li class="listitem">
            if the attribute is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;</span></code>, the attribute becomes instead
            <code class="computeroutput"><span class="identifier">T</span></code> or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>, respectively; and
          </li>
<li class="listitem">
            if the attribute is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;&gt;</span></code> or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;&gt;&gt;</span></code>, the result becomes <code class="computeroutput"><span class="identifier">none</span></code> instead.
          </li>
</ul></div>
<h5>
<a name="boost_parser.tutorial.attribute_generation.h6"></a>
        <span class="phrase"><a name="boost_parser.tutorial.attribute_generation.formation_of_containers_in_attributes"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation.formation_of_containers_in_attributes">Formation
        of containers in attributes</a>
      </h5>
<p>
        The rule for forming containers from non-containers is simple. You get a
        vector from any of the repeating parsers, like <code class="computeroutput"><span class="special">+</span><span class="identifier">p</span></code>, <code class="computeroutput"><span class="special">*</span><span class="identifier">p</span></code>, <code class="computeroutput"><span class="identifier">repeat</span><span class="special">(</span><span class="number">3</span><span class="special">)[</span><span class="identifier">p</span><span class="special">]</span></code>, etc.
        The value type of the vector is <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>.
      </p>
<p>
        Another rule for sequence containers is that a value <code class="computeroutput"><span class="identifier">x</span></code>
        and a container <code class="computeroutput"><span class="identifier">c</span></code> containing
        elements of <code class="computeroutput"><span class="identifier">x</span></code>'s type will
        form a single container. However, <code class="computeroutput"><span class="identifier">x</span></code>'s
        type must be exactly the same as the elements in <code class="computeroutput"><span class="identifier">c</span></code>.
        There is an exception to this in the special case for strings and characters
        noted above. For instance, consider the attribute of <code class="computeroutput"><span class="identifier">char_</span>
        <span class="special">&gt;&gt;</span> <span class="identifier">string</span><span class="special">(</span><span class="string">"str"</span><span class="special">)</span></code>. In the non-Unicode code path, <code class="computeroutput"><span class="identifier">char_</span></code>'s attribute type is guaranteed to
        be <code class="computeroutput"><span class="keyword">char</span></code>, so <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">char_</span> <span class="special">&gt;&gt;</span> <span class="identifier">string</span><span class="special">(</span><span class="string">"str"</span><span class="special">))</span></code> is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
        If you are parsing UTF-8 in the Unicode code path, <code class="computeroutput"><span class="identifier">char_</span></code>'s
        attribute type is <code class="computeroutput"><span class="keyword">char32_t</span></code>,
        and the special rule makes it also produce a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
        Otherwise, the attribute for <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">char_</span> <span class="special">&gt;&gt;</span> <span class="identifier">string</span><span class="special">(</span><span class="string">"str"</span><span class="special">))</span></code> would be <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="keyword">char32_t</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span></code>.
      </p>
<p>
        Again, there are no special rules for combining values and containers. Every
        combination results from an exact match, or fall into the string+character
        special case.
      </p>
<h5>
<a name="boost_parser.tutorial.attribute_generation.h7"></a>
        <span class="phrase"><a name="boost_parser.tutorial.attribute_generation.another_special_case___code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__string__phrase___code__assignment"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation.another_special_case___code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__string__phrase___code__assignment">Another
        special case: <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> assignment</a>
      </h5>
<p>
        <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> can be assigned from a <code class="computeroutput"><span class="keyword">char</span></code>. This is dumb. But, we're stuck with
        it. When you write a parser with a <code class="computeroutput"><span class="keyword">char</span></code>
        attribute, and you try to parse it into a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>,
        you've almost certainly made a mistake. More importantly, if you write this:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">result</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"3"</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">,</span> <span class="identifier">result</span><span class="special">);</span>
</pre>
<p>
        ... you are even more likely to have made a mistake. Though this should work,
        because the assignment in <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">s</span><span class="special">;</span> <span class="identifier">s</span>
        <span class="special">=</span> <span class="number">3</span><span class="special">;</span></code> is well-formed, Boost.Parser forbids it.
        If you write parsing code like the snippet above, you will get a static assertion.
        If you really do want to assign a <code class="computeroutput"><span class="keyword">float</span></code>
        or whatever to a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>, do it in a semantic action.
      </p>
<h5>
<a name="boost_parser.tutorial.attribute_generation.h8"></a>
        <span class="phrase"><a name="boost_parser.tutorial.attribute_generation.examples_of_attributes_generated_by_sequence_and_alternative_parsers"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation.examples_of_attributes_generated_by_sequence_and_alternative_parsers">Examples
        of attributes generated by sequence and alternative parsers</a>
      </h5>
<p>
        In the table: <code class="computeroutput"><span class="identifier">a</span></code> is a semantic
        action; and <code class="computeroutput"><span class="identifier">p</span></code>, <code class="computeroutput"><span class="identifier">p1</span></code>, <code class="computeroutput"><span class="identifier">p2</span></code>,
        ... are parsers that generate attributes. Note that only <code class="computeroutput"><span class="special">&gt;&gt;</span></code>
        is used here; <code class="computeroutput"><span class="special">&gt;</span></code> has the exact
        same attribute generation rules.
      </p>
<div class="table">
<a name="boost_parser.tutorial.attribute_generation.t2"></a><p class="title"><b>Table 25.10. Sequence and Alternative Combining Operations and Their Attributes</b></p>
<div class="table-contents"><table class="table" summary="Sequence and Alternative Combining Operations and Their Attributes">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
                <p>
                  Expression
                </p>
              </th>
<th>
                <p>
                  Attribute Type
                </p>
              </th>
</tr></thead>
<tbody>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a>
                  <span class="special">&gt;&gt;</span> <a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">&gt;&gt;</span>
                  <a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a>
                  <span class="special">&gt;&gt;</span> <span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1adf23d22a6b9aa56e8e5d5c5bc2e97881.html" title="Global cu">cu</a>
                  <span class="special">&gt;&gt;</span> <a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7e079d756d52cf5fc94cbdca53bb8b4f.html" title="Function template string">string</a><span class="special">(</span><span class="string">"str"</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7e079d756d52cf5fc94cbdca53bb8b4f.html" title="Function template string">string</a><span class="special">(</span><span class="string">"str"</span><span class="special">)</span> <span class="special">&gt;&gt;</span>
                  <a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1adf23d22a6b9aa56e8e5d5c5bc2e97881.html" title="Global cu">cu</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">*</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1adf23d22a6b9aa56e8e5d5c5bc2e97881.html" title="Global cu">cu</a> <span class="special">&gt;&gt;</span>
                  <a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7e079d756d52cf5fc94cbdca53bb8b4f.html" title="Function template string">string</a><span class="special">(</span><span class="string">"str"</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7e079d756d52cf5fc94cbdca53bb8b4f.html" title="Function template string">string</a><span class="special">(</span><span class="string">"str"</span><span class="special">)</span> <span class="special">&gt;&gt;</span>
                  <span class="special">*</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1adf23d22a6b9aa56e8e5d5c5bc2e97881.html" title="Global cu">cu</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">&gt;&gt;</span>
                  <span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">*</span><span class="identifier">p</span>
                  <span class="special">&gt;&gt;</span> <span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">&gt;&gt;</span>
                  <span class="special">*</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">*</span><span class="identifier">p</span>
                  <span class="special">&gt;&gt;</span> <span class="special">-</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">-</span><span class="identifier">p</span>
                  <span class="special">&gt;&gt;</span> <span class="special">*</span><span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> if <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">char</span></code>
                  or <code class="computeroutput"><span class="keyword">char32_t</span></code>, otherwise
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7e079d756d52cf5fc94cbdca53bb8b4f.html" title="Function template string">string</a><span class="special">(</span><span class="string">"str"</span><span class="special">)</span> <span class="special">&gt;&gt;</span>
                  <span class="special">-</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1adf23d22a6b9aa56e8e5d5c5bc2e97881.html" title="Global cu">cu</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">-</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1adf23d22a6b9aa56e8e5d5c5bc2e97881.html" title="Global cu">cu</a> <span class="special">&gt;&gt;</span>
                  <a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7e079d756d52cf5fc94cbdca53bb8b4f.html" title="Function template string">string</a><span class="special">(</span><span class="string">"str"</span><span class="special">)</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="special">!</span><span class="identifier">p1</span>
                  <span class="special">|</span> <span class="identifier">p2</span><span class="special">[</span><span class="identifier">a</span><span class="special">]</span></code>
                </p>
              </td>
<td>
                <p>
                  None.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">|</span>
                  <span class="identifier">p</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">|</span>
                  <span class="identifier">p2</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p</span> <span class="special">|</span>
                  </code><code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">|</span>
                  <span class="identifier">p2</span> <span class="special">|</span>
                  <a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p2</span><span class="special">)&gt;&gt;</span></code>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">p1</span> <span class="special">|</span>
                  <span class="identifier">p2</span><span class="special">[</span><span class="identifier">a</span><span class="special">]</span>
                  <span class="special">|</span> <span class="identifier">p3</span></code>
                </p>
              </td>
<td>
                <p>
                  <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p1</span><span class="special">),</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p3</span><span class="special">)&gt;&gt;</span></code>
                </p>
              </td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><h5>
<a name="boost_parser.tutorial.attribute_generation.h9"></a>
        <span class="phrase"><a name="boost_parser.tutorial.attribute_generation.controlling_attribute_generation_with__globalname_alt__boost__parser__merge___code__phrase_role__identifier__merge__phrase__phrase_role__special______phrase___code___globalname__and__globalname_alt__boost__parser__separate___code__phrase_role__identifier__separate__phrase__phrase_role__special______phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation.controlling_attribute_generation_with__globalname_alt__boost__parser__merge___code__phrase_role__identifier__merge__phrase__phrase_role__special______phrase___code___globalname__and__globalname_alt__boost__parser__separate___code__phrase_role__identifier__separate__phrase__phrase_role__special______phrase___code___globalname_">Controlling
        attribute generation with merge[]
        and separate[]</a>
      </h5>
<p>
        As we saw in the previous <a class="link" href="tutorial.html#boost_parser.tutorial.parsing_into__struct_s_and__class_es" title="Parsing into structs and classes">Parsing
        into <code class="computeroutput"><span class="keyword">struct</span></code>s and <code class="computeroutput"><span class="keyword">class</span></code>es</a> section, if you parse two strings
        in a row, you get two separate strings in the resulting attribute. The parser
        from that example was this:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">employee_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="string">"employee"</span><span class="special">)</span>
    <span class="special">&gt;&gt;</span> <span class="char">'{'</span>
    <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
    <span class="special">&gt;&gt;</span> <span class="identifier">quoted_string</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
    <span class="special">&gt;&gt;</span> <span class="identifier">quoted_string</span> <span class="special">&gt;&gt;</span> <span class="char">','</span>
    <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span>
    <span class="special">&gt;&gt;</span> <span class="char">'}'</span><span class="special">;</span>
</pre>
<p>
        <code class="computeroutput"><span class="identifier">employee_parser</span></code>'s attribute
        is <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span></code>.
        The two <code class="computeroutput"><span class="identifier">quoted_string</span></code> parsers
        produce <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> attributes, and those attributes
        are not combined. That is the default behavior, and it is just what we want
        for this case; we don't want the first and last name fields to be jammed
        together such that we can't tell where one name ends and the other begins.
        What if we were parsing some string that consisted of a prefix and a suffix,
        and the prefix and suffix were defined separately for reuse elsewhere?
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">prefix</span> <span class="special">=</span> <span class="comment">/* ... */</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">suffix</span> <span class="special">=</span> <span class="comment">/* ... */</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">special_string</span> <span class="special">=</span> <span class="identifier">prefix</span> <span class="special">&gt;&gt;</span> <span class="identifier">suffix</span><span class="special">;</span>
<span class="comment">// Continue to use prefix and suffix to make other parsers....</span>
</pre>
<p>
        In this case, we might want to use these separate parsers, but want <code class="computeroutput"><span class="identifier">special_string</span></code> to produce a single <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
        for its attribute. <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a11728b9935b826cf6a066766b347f17b.html" title="Global merge">merge[]</a></code> exists for this purpose.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">prefix</span> <span class="special">=</span> <span class="comment">/* ... */</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">suffix</span> <span class="special">=</span> <span class="comment">/* ... */</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">special_string</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">merge</span><span class="special">[</span><span class="identifier">prefix</span> <span class="special">&gt;&gt;</span> <span class="identifier">suffix</span><span class="special">];</span>
</pre>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a11728b9935b826cf6a066766b347f17b.html" title="Global merge">merge[]</a></code> only applies to sequence parsers
        (like <code class="computeroutput"><span class="identifier">p1</span> <span class="special">&gt;&gt;</span>
        <span class="identifier">p2</span></code>), and forces all subparsers
        in the sequence parser to use the same variable for their attribute.
      </p>
<p>
        Another directive, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a1c4c5ec9144e8f4d1e1e1cb848a0ae04.html" title="Global separate">separate[]</a></code>,
        also applies only to sequence parsers, but does the opposite of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a11728b9935b826cf6a066766b347f17b.html" title="Global merge">merge[]</a></code>. If forces all the attributes
        produced by the subparsers of the sequence parser to stay separate, even
        if they would have combined. For instance, consider this parser.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">string_and_char</span> <span class="special">=</span> <span class="special">+</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="char">' '</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">cp</span><span class="special">;</span>
</pre>
<p>
        <code class="computeroutput"><span class="identifier">string_and_char</span></code> matches one
        or more <code class="computeroutput"><span class="char">'a'</span></code>s, followed by some
        other character. As written above, <code class="computeroutput"><span class="identifier">string_and_char</span></code>
        produces a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>, and the final character is appended
        to the string, after all the <code class="computeroutput"><span class="char">'a'</span></code>s.
        However, if you wanted to store the final character as a separate value,
        you would use <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a1c4c5ec9144e8f4d1e1e1cb848a0ae04.html" title="Global separate">separate[]</a></code>.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">string_and_char</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">separate</span><span class="special">[+</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="char">' '</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">cp</span><span class="special">];</span>
</pre>
<p>
        With this change, <code class="computeroutput"><span class="identifier">string_and_char</span></code>
        produces the attribute <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">char32_t</span><span class="special">&gt;</span></code>.
      </p>
<h5>
<a name="boost_parser.tutorial.attribute_generation.h10"></a>
        <span class="phrase"><a name="boost_parser.tutorial.attribute_generation._globalname_alt__boost__parser__merge___code__phrase_role__identifier__merge__phrase__phrase_role__special______phrase___code___globalname__and__globalname_alt__boost__parser__separate___code__phrase_role__identifier__separate__phrase__phrase_role__special______phrase___code___globalname__in_more_detail"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation._globalname_alt__boost__parser__merge___code__phrase_role__identifier__merge__phrase__phrase_role__special______phrase___code___globalname__and__globalname_alt__boost__parser__separate___code__phrase_role__identifier__separate__phrase__phrase_role__special______phrase___code___globalname__in_more_detail">merge[] and separate[]
        in more detail</a>
      </h5>
<p>
        As mentioned previously, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a11728b9935b826cf6a066766b347f17b.html" title="Global merge">merge[]</a></code>
        applies only to sequence parsers. All subparsers must have the same attribute,
        or produce no attribute at all. At least one subparser must produce an attribute.
        When you use <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a11728b9935b826cf6a066766b347f17b.html" title="Global merge">merge[]</a></code>, you create a <span class="emphasis"><em>combining
        group</em></span>. Every parser in a combining group uses the same variable
        for its attribute. No parser in a combining group interacts with the attributes
        of any parsers outside of its combining group. Combining groups are disjoint;
        <code class="computeroutput"><span class="identifier">merge</span><span class="special">[/*...*/]</span>
        <span class="special">&gt;&gt;</span> <span class="identifier">merge</span><span class="special">[/*...*/]</span></code> will produce a tuple of two attributes,
        not one.
      </p>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a1c4c5ec9144e8f4d1e1e1cb848a0ae04.html" title="Global separate">separate[]</a></code> also applies only to sequence
        parsers. When you use <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a1c4c5ec9144e8f4d1e1e1cb848a0ae04.html" title="Global separate">separate[]</a></code>,
        you disable interaction of all the subparsers' attributes with adjacent attributes,
        whether they are inside or outside the <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a1c4c5ec9144e8f4d1e1e1cb848a0ae04.html" title="Global separate">separate[]</a></code>
        directive; you force each subparser to have a separate attribute.
      </p>
<p>
        The rules for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a11728b9935b826cf6a066766b347f17b.html" title="Global merge">merge[]</a></code> and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a1c4c5ec9144e8f4d1e1e1cb848a0ae04.html" title="Global separate">separate[]</a></code>
        overrule the steps of the algorithm described above for combining the attributes
        of a sequence parser. Consider an example.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">parser</span> <span class="special">=</span>
    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">merge</span><span class="special">[(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="string">"abc"</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="string">"ghi"</span><span class="special">)];</span>
</pre>
<p>
        You might think that <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">parser</span><span class="special">)</span></code> would be <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span></code>.
        It is not. The parser above does not even compile. Since we created a merge
        group above, we disabled the default behavior in which the <code class="computeroutput"><span class="identifier">char_</span></code> parsers would have collapsed into
        the <code class="computeroutput"><span class="identifier">string</span></code> parser that preceded
        them. Since they are all treated as separate entities, and since they have
        different attribute types, the use of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a11728b9935b826cf6a066766b347f17b.html" title="Global merge">merge[]</a></code>
        is an error.
      </p>
<p>
        Many directives create a new parser out of the parser they are given. <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a11728b9935b826cf6a066766b347f17b.html" title="Global merge">merge[]</a></code> and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a1c4c5ec9144e8f4d1e1e1cb848a0ae04.html" title="Global separate">separate[]</a></code>
        do not. Since they operate only on sequence parsers, all they do is create
        a copy of the sequence parser they are given. The <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1seq__parser.html" title="Struct template seq_parser">seq_parser</a></code> template has a template
        parameter <code class="computeroutput"><span class="identifier">CombiningGroups</span></code>,
        and all <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a11728b9935b826cf6a066766b347f17b.html" title="Global merge">merge[]</a></code> and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a1c4c5ec9144e8f4d1e1e1cb848a0ae04.html" title="Global separate">separate[]</a></code>
        do is take a given <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1seq__parser.html" title="Struct template seq_parser">seq_parser</a></code> and create a copy
        of it with a different <code class="computeroutput"><span class="identifier">CombiningGroups</span></code>
        template parameter. This means that <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a11728b9935b826cf6a066766b347f17b.html" title="Global merge">merge[]</a></code>
        and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a1c4c5ec9144e8f4d1e1e1cb848a0ae04.html" title="Global separate">separate[]</a></code> are can be ignored in <code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;&gt;</span></code>
        expressions much like parentheses are. Consider an example.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">parser1</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">separate</span><span class="special">[</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">;</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">parser2</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">[</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="char">' '</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">;</span>
</pre>
<p>
        Note that <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a1c4c5ec9144e8f4d1e1e1cb848a0ae04.html" title="Global separate">separate[]</a></code> is a no-op here; it's only
        being used this way for this example. These parsers have different attribute
        types. <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">parser1</span><span class="special">)</span></code>
        is <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">(</span><span class="keyword">int</span><span class="special">,</span>
        <span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span></code>. <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">parser2</span><span class="special">)</span></code> is <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">(</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a><span class="special">(</span><span class="keyword">int</span><span class="special">,</span>
        <span class="keyword">int</span><span class="special">),</span> <span class="keyword">int</span><span class="special">)</span></code>. This
        is because <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">[]</span></code>
        wraps its given parser in a new parser. <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a11728b9935b826cf6a066766b347f17b.html" title="Global merge">merge[]</a></code>
        does not. That's why, even though <code class="computeroutput"><span class="identifier">parser1</span></code>
        and <code class="computeroutput"><span class="identifier">parser2</span></code> look so structurally
        similar, they have different attributes.
      </p>
<h5>
<a name="boost_parser.tutorial.attribute_generation.h11"></a>
        <span class="phrase"><a name="boost_parser.tutorial.attribute_generation._globalname_alt__boost__parser__transform___code__phrase_role__identifier__transform__phrase__phrase_role__special_____phrase__phrase_role__identifier__f__phrase__phrase_role__special_______phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation._globalname_alt__boost__parser__transform___code__phrase_role__identifier__transform__phrase__phrase_role__special_____phrase__phrase_role__identifier__f__phrase__phrase_role__special_______phrase___code___globalname_"><code class="computeroutput">transform(f)[]</code></a>
      </h5>
<p>
        <code class="computeroutput">transform(f)[]</code>
        is a directive that transforms the attribute of a parser using the given
        function <code class="computeroutput"><span class="identifier">f</span></code>. For example:
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">str_sum</span> <span class="special">=</span> <span class="special">[&amp;](</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span> <span class="special">{</span>
    <span class="keyword">int</span> <span class="identifier">retval</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
    <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span> <span class="identifier">ch</span> <span class="special">:</span> <span class="identifier">s</span><span class="special">)</span> <span class="special">{</span>
        <span class="identifier">retval</span> <span class="special">+=</span> <span class="identifier">ch</span> <span class="special">-</span> <span class="char">'0'</span><span class="special">;</span>
    <span class="special">}</span>
    <span class="keyword">return</span> <span class="identifier">retval</span><span class="special">;</span>
<span class="special">};</span>

<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="special">+</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">str</span> <span class="special">=</span> <span class="string">"012345"</span><span class="special">;</span>

<span class="keyword">auto</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">str_sum</span><span class="special">)[</span><span class="identifier">parser</span><span class="special">]);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">result</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(*</span><span class="identifier">result</span> <span class="special">==</span> <span class="number">15</span><span class="special">);</span>
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same_v</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">result</span><span class="special">),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;&gt;);</span>
</pre>
<p>
      </p>
<p>
        Here, we have a function <code class="computeroutput"><span class="identifier">str_sum</span></code>
        that we use for <code class="computeroutput"><span class="identifier">f</span></code>. It assumes
        each character in the given <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
        <code class="computeroutput"><span class="identifier">s</span></code> is a digit, and returns
        the sum of all the digits in <code class="computeroutput"><span class="identifier">s</span></code>.
        Out parser <code class="computeroutput"><span class="identifier">parser</span></code> would normally
        return a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>. However, since <code class="computeroutput"><span class="identifier">str_sum</span></code>
        returns a different type — <code class="computeroutput"><span class="keyword">int</span></code>
        — that is the attribute type of the full parser, <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">by_value_str_sum</span><span class="special">)[</span><span class="identifier">parser</span><span class="special">]</span></code>, as you can see from the <code class="computeroutput"><span class="keyword">static_assert</span></code>.
      </p>
<p>
        As is the case with attributes all throughout Boost.Parser, the attribute
        passed to <code class="computeroutput"><span class="identifier">f</span></code> will be moved.
        You can take it by <code class="computeroutput"><span class="keyword">const</span> <span class="special">&amp;</span></code>,
        <code class="computeroutput"><span class="special">&amp;&amp;</span></code>, or by value.
      </p>
<p>
        No distinction is made between parsers with and without an attribute, because
        there is a Regular special no-attribute type that is generated by parsers
        with no attribute. You may therefore write something like <code class="computeroutput">transform<span class="special">(</span><span class="identifier">f</span><span class="special">)[</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a><span class="special">]</span></code>, and Boost.Parser will happily call <code class="computeroutput"><span class="identifier">f</span></code> with this special no-attribute type.
      </p>
<h5>
<a name="boost_parser.tutorial.attribute_generation.h12"></a>
        <span class="phrase"><a name="boost_parser.tutorial.attribute_generation.other_directives_that_affect_attribute_generation"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation.other_directives_that_affect_attribute_generation">Other
        directives that affect attribute generation</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aba924d9dafe70d651680058e6004f31e.html" title="Global omit">omit</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>
        disables attribute generation for the parser <code class="computeroutput"><span class="identifier">p</span></code>.
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3960485823df80f6a97f87e811cf7b.html" title="Global raw">raw</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>
        changes the attribute from <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
        to a view that indicates the subrange of the input that was matched by <code class="computeroutput"><span class="identifier">p</span></code>. <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a8890ba07e65b9e7b1b0f238e94498d.html" title="Global string_view">string_view</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code> is just
        like <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3960485823df80f6a97f87e811cf7b.html" title="Global raw">raw</a><span class="special">[</span><span class="identifier">p</span><span class="special">]</span></code>,
        except that it produces <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string_view</span></code>s.
        See <a class="link" href="tutorial.html#boost_parser.tutorial.directives" title="Directives">Directives</a> for
        details.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.the__parse____api"></a><a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api" title="The parse() API">The <code class="computeroutput"><span class="identifier">parse</span><span class="special">()</span></code> API</a>
</h3></div></div></div>
<p>
        There are multiple top-level parse functions. They have some things in common:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            They each return a value contextually convertible to <code class="computeroutput"><span class="keyword">bool</span></code>.
          </li>
<li class="listitem">
            They each take at least a range to parse and a parser. The "range
            to parse" may be an iterator/sentinel pair or an single range object.
          </li>
<li class="listitem">
            They each require forward iterability of the range to parse.
          </li>
<li class="listitem">
            They each accept any range with a character element type. This means
            that they can each parse ranges of <code class="computeroutput"><span class="keyword">char</span></code>,
            <code class="computeroutput"><span class="keyword">wchar_t</span></code>, <code class="computeroutput"><span class="identifier">char8_t</span></code>,
            <code class="computeroutput"><span class="keyword">char16_t</span></code>, or <code class="computeroutput"><span class="keyword">char32_t</span></code>.
          </li>
<li class="listitem">
            The overloads with <code class="computeroutput"><span class="identifier">prefix_</span></code>
            in their name take an iterator/sentinel pair. For example <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa3a1f9c9842a7d78f838d924ec01f46a.html" title="Function template prefix_parse">prefix_parse</a><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">p</span><span class="special">,</span> <a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a13a98612c59d598c30d400ff92c7765f.html" title="Global ws">ws</a><span class="special">)</span></code>,
            which parses the range <code class="computeroutput"><span class="special">[</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">)</span></code>,
            advancing <code class="computeroutput"><span class="identifier">first</span></code> as it
            goes. If the parse succeeds, the entire input may or may not have been
            matched. The value of <code class="computeroutput"><span class="identifier">first</span></code>
            will indicate the last location within the input that <code class="computeroutput"><span class="identifier">p</span></code>
            matched. The <span class="bold"><strong>whole</strong></span> input was matched
            if and only if <code class="computeroutput"><span class="identifier">first</span> <span class="special">==</span> <span class="identifier">last</span></code>
            after the call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>.
          </li>
<li class="listitem">
            When you call any of the range overloads of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>,
            for example <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse</a><span class="special">(</span><span class="identifier">r</span><span class="special">,</span> <span class="identifier">p</span><span class="special">,</span> <a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a13a98612c59d598c30d400ff92c7765f.html" title="Global ws">ws</a><span class="special">)</span></code>, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
            only indicates success if <span class="bold"><strong>all</strong></span> of <code class="computeroutput"><span class="identifier">r</span></code> was matched by <code class="computeroutput"><span class="identifier">p</span></code>.
          </li>
</ul></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          <code class="computeroutput"><span class="keyword">wchar_t</span></code> is an accepted value
          type for the input. Please note that this is interpreted as UTF-16 on MSVC,
          and UTF-32 everywhere else.
        </p></td></tr>
</table></div>
<h5>
<a name="boost_parser.tutorial.the__parse____api.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the__parse____api.the_overloads"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api.the_overloads">The overloads</a>
      </h5>
<p>
        There are eight overloads of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa3a1f9c9842a7d78f838d924ec01f46a.html" title="Function template prefix_parse">prefix_parse()</a></code> combined, because there
        are three either/or options in how you call them.
      </p>
<h5>
<a name="boost_parser.tutorial.the__parse____api.h1"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the__parse____api.iterator_sentinel_versus_range"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api.iterator_sentinel_versus_range">Iterator/sentinel
        versus range</a>
      </h5>
<p>
        You can call <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa3a1f9c9842a7d78f838d924ec01f46a.html" title="Function template prefix_parse">prefix_parse()</a></code>
        with an iterator and sentinel that delimit a range of character values. For
        example:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">p</span> <span class="special">=</span> <span class="comment">/* some parser ... */</span><span class="special">;</span>

<span class="keyword">char</span> <span class="keyword">const</span> <span class="special">*</span> <span class="identifier">str_1</span> <span class="special">=</span> <span class="comment">/* ... */</span><span class="special">;</span>
<span class="comment">// Using null_sentinel, str_1 can point to three billion characters, and</span>
<span class="comment">// we can call prefix_parse() without having to find the end of the string first.</span>
<span class="keyword">auto</span> <span class="identifier">result_1</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">prefix_parse</span><span class="special">(</span><span class="identifier">str_1</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">null_sentinel</span><span class="special">,</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>

<span class="keyword">char</span> <span class="identifier">str_2</span><span class="special">[]</span> <span class="special">=</span> <span class="comment">/* ... */</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">result_2</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">prefix_parse</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">begin</span><span class="special">(</span><span class="identifier">str_2</span><span class="special">),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">end</span><span class="special">(</span><span class="identifier">str_2</span><span class="special">),</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
</pre>
<p>
        The iterator/sentinel overloads can parse successfully without matching the
        entire input. You can tell if the entire input was matched by checking if
        <code class="computeroutput"><span class="identifier">first</span> <span class="special">==</span>
        <span class="identifier">last</span></code> is true after <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa3a1f9c9842a7d78f838d924ec01f46a.html" title="Function template prefix_parse">prefix_parse()</a></code> returns.
      </p>
<p>
        By contrast, you call <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        with a range of character values. When the range is a reference to an array
        of characters, any terminating <code class="computeroutput"><span class="number">0</span></code>
        is ignored; this allows calls like <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse</a><span class="special">(</span><span class="string">"str"</span><span class="special">,</span>
        <span class="identifier">p</span><span class="special">)</span></code>
        to work naturally.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">p</span> <span class="special">=</span> <span class="comment">/* some parser ... */</span><span class="special">;</span>

<span class="identifier">std</span><span class="special">::</span><span class="identifier">u8string</span> <span class="identifier">str_1</span> <span class="special">=</span> <span class="string">"str"</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">result_1</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">str_1</span><span class="special">,</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>

<span class="comment">// The null terminator is ignored.  This call parses s-t-r, not s-t-r-0.</span>
<span class="keyword">auto</span> <span class="identifier">result_2</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">U</span><span class="string">"str"</span><span class="special">,</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>

<span class="keyword">char</span> <span class="keyword">const</span> <span class="special">*</span> <span class="identifier">str_3</span> <span class="special">=</span> <span class="string">"str"</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">result_3</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">null_term</span><span class="special">(</span><span class="identifier">str_3</span><span class="special">)</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf16</span><span class="special">,</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
</pre>
<p>
        Since there is no way to indicate that <code class="computeroutput"><span class="identifier">p</span></code>
        matches the input, but only a prefix of the input was matched, the range
        (non-iterator/sentinel) overloads of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        indicate failure if the entire input is not matched.
      </p>
<h5>
<a name="boost_parser.tutorial.the__parse____api.h2"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the__parse____api.with_or_without_an_attribute_out_parameter"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api.with_or_without_an_attribute_out_parameter">With
        or without an attribute out-parameter</a>
      </h5>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">p</span> <span class="special">=</span> <span class="char">'"'</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="char">'"'</span><span class="special">;</span>
<span class="keyword">char</span> <span class="keyword">const</span> <span class="special">*</span> <span class="identifier">str</span> <span class="special">=</span> <span class="string">"\"two words\""</span> <span class="special">;</span>

<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">result_1</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">const</span> <span class="identifier">success</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">result_1</span><span class="special">);</span>   <span class="comment">// success is true; result_1 is "two words"</span>
<span class="keyword">auto</span> <span class="identifier">result_2</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">p</span><span class="special">);</span>                  <span class="comment">// !!result_2 is true; *result_2 is "two words"</span>
</pre>
<p>
        When you call <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> <span class="bold"><strong>with</strong></span>
        an attribute out-parameter and parser <code class="computeroutput"><span class="identifier">p</span></code>,
        the expected type is <span class="bold"><strong>something like</strong></span> <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>.
        It doesn't have to be exactly that; I'll explain in a bit. The return type
        is <code class="computeroutput"><span class="keyword">bool</span></code>.
      </p>
<p>
        When you call <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> <span class="bold"><strong>without</strong></span>
        an attribute out-parameter and parser <code class="computeroutput"><span class="identifier">p</span></code>,
        the return type is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)&gt;</span></code>.
        Note that when <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>
        is itself an <code class="computeroutput"><span class="identifier">optional</span></code>, the
        return type is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;...&gt;&gt;</span></code>. Each of those optionals tells
        you something different. The outer one tells you whether the parse succeeded.
        If so, the parser was successful, but it still generates an attribute that
        is an <code class="computeroutput"><span class="identifier">optional</span></code> — that's
        the inner one.
      </p>
<h5>
<a name="boost_parser.tutorial.the__parse____api.h3"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the__parse____api.with_or_without_a_skipper"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api.with_or_without_a_skipper">With
        or without a skipper</a>
      </h5>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">p</span> <span class="special">=</span> <span class="char">'"'</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="char">'"'</span><span class="special">;</span>
<span class="keyword">char</span> <span class="keyword">const</span> <span class="special">*</span> <span class="identifier">str</span> <span class="special">=</span> <span class="string">"\"two words\""</span> <span class="special">;</span>

<span class="keyword">auto</span> <span class="identifier">result_1</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">p</span><span class="special">);</span>         <span class="comment">// !!result_1 is true; *result_1 is "two words"</span>
<span class="keyword">auto</span> <span class="identifier">result_2</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span> <span class="comment">// !!result_2 is true; *result_2 is "twowords"</span>
</pre>
<h5>
<a name="boost_parser.tutorial.the__parse____api.h4"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the__parse____api.compatibility_of_attribute_out_parameters"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api.compatibility_of_attribute_out_parameters">Compatibility
        of attribute out-parameters</a>
      </h5>
<p>
        For any call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> that takes an attribute
        out-parameter, like <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse</a><span class="special">(</span><span class="string">"str"</span><span class="special">,</span>
        <span class="identifier">p</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">,</span> <span class="identifier">out</span><span class="special">)</span></code>,
        the call is well-formed for a number of possible types of <code class="computeroutput"><span class="identifier">out</span></code>;
        <code class="computeroutput"><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">out</span><span class="special">)</span></code> does
        not need to be exactly <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>.
      </p>
<p>
        For instance, this is well-formed code that does not abort (remember that
        the attribute type of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7e079d756d52cf5fc94cbdca53bb8b4f.html" title="Function template string">string()</a></code>
        is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>):
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="string">"foo"</span><span class="special">);</span>

<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span> <span class="identifier">result</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">const</span> <span class="identifier">success</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">result</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">success</span> <span class="special">&amp;&amp;</span> <span class="identifier">result</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;({</span><span class="char">'f'</span><span class="special">,</span> <span class="char">'o'</span><span class="special">,</span> <span class="char">'o'</span><span class="special">}));</span>
</pre>
<p>
        Even though <code class="computeroutput"><span class="identifier">p</span></code> generates a
        <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> attribute, when it actually takes
        the data it generates and writes it into an attribute, it only assumes that
        the attribute is a <code class="computeroutput"><span class="identifier">container</span></code>
        (see <a class="link" href="concepts.html" title="Concepts">Concepts</a>), not that it
        is some particular container type. It will happily <code class="computeroutput"><span class="identifier">insert</span><span class="special">()</span></code> into a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
        or a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span></code> all
        the same. <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span></code>
        are both containers of <code class="computeroutput"><span class="keyword">char</span></code>,
        but it will also insert into a container with a different element type.
        <code class="computeroutput"><span class="identifier">p</span></code> just needs to be able to
        insert the elements it produces into the attribute-container. As long as
        an implicit conversion allows that to work, everything is fine:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="string">"foo"</span><span class="special">);</span>

<span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">result</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">const</span> <span class="identifier">success</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">result</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">success</span> <span class="special">&amp;&amp;</span> <span class="identifier">result</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;({</span><span class="char">'f'</span><span class="special">,</span> <span class="char">'o'</span><span class="special">,</span> <span class="char">'o'</span><span class="special">}));</span>
</pre>
<p>
        This works, too, even though it requires inserting elements from a generated
        sequence of <code class="computeroutput"><span class="keyword">char32_t</span></code> into a
        container of <code class="computeroutput"><span class="keyword">char</span></code> (remember
        that the attribute type of <code class="computeroutput"><span class="special">+</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a3d982dd5003327f579e689e9fbbf7cb4.html" title="Global cp">cp</a></code>
        is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char32_t</span><span class="special">&gt;</span></code>):
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">p</span> <span class="special">=</span> <span class="special">+</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">cp</span><span class="special">;</span>

<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">result</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">const</span> <span class="identifier">success</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">result</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">success</span> <span class="special">&amp;&amp;</span> <span class="identifier">result</span> <span class="special">==</span> <span class="string">"foo"</span><span class="special">);</span>
</pre>
<p>
        This next example works as well, even though the change to a container is
        not at the top level. It is an element of the result tuple:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">p</span> <span class="special">=</span> <span class="special">+(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">cp</span> <span class="special">-</span> <span class="char">' '</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="char">' '</span> <span class="special">&gt;&gt;</span> <span class="identifier">string</span><span class="special">(</span><span class="string">"foo"</span><span class="special">);</span>

<span class="keyword">using</span> <span class="identifier">attr_type</span> <span class="special">=</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">u8</span><span class="string">""</span><span class="special">,</span> <span class="identifier">p</span><span class="special">));</span>
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same_v</span><span class="special">&lt;</span>
              <span class="identifier">attr_type</span><span class="special">,</span>
              <span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;&gt;&gt;);</span>

<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>

<span class="special">{</span>
    <span class="comment">// This is similar to attr_type, with the first std::string changed to a std::vector&lt;int&gt;.</span>
    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">result</span><span class="special">;</span>
    <span class="keyword">bool</span> <span class="keyword">const</span> <span class="identifier">success</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">u8</span><span class="string">"rôle foo"</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf8</span><span class="special">,</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">result</span><span class="special">);</span>
    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">success</span><span class="special">);</span>
    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">result</span><span class="special">,</span> <span class="number">0</span><span class="identifier">_c</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;({</span><span class="char">'r'</span><span class="special">,</span> <span class="identifier">U</span><span class="char">'ô'</span><span class="special">,</span> <span class="char">'l'</span><span class="special">,</span> <span class="char">'e'</span><span class="special">}));</span>
    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">result</span><span class="special">,</span> <span class="number">1</span><span class="identifier">_c</span><span class="special">)</span> <span class="special">==</span> <span class="string">"foo"</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">{</span>
    <span class="comment">// This time, we have a std::vector&lt;char&gt; instead of a std::vector&lt;int&gt;.</span>
    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">result</span><span class="special">;</span>
    <span class="keyword">bool</span> <span class="keyword">const</span> <span class="identifier">success</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">u8</span><span class="string">"rôle foo"</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf8</span><span class="special">,</span> <span class="identifier">p</span><span class="special">,</span> <span class="identifier">result</span><span class="special">);</span>
    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">success</span><span class="special">);</span>
    <span class="comment">// The 4 code points "rôle" get transcoded to 5 UTF-8 code points to fit in the std::string.</span>
    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">result</span><span class="special">,</span> <span class="number">0</span><span class="identifier">_c</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;({</span><span class="char">'r'</span><span class="special">,</span> <span class="special">(</span><span class="keyword">char</span><span class="special">)</span><span class="number">0xc3</span><span class="special">,</span> <span class="special">(</span><span class="keyword">char</span><span class="special">)</span><span class="number">0xb4</span><span class="special">,</span> <span class="char">'l'</span><span class="special">,</span> <span class="char">'e'</span><span class="special">}));</span>
    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">result</span><span class="special">,</span> <span class="number">1</span><span class="identifier">_c</span><span class="special">)</span> <span class="special">==</span> <span class="string">"foo"</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
        As indicated in the inline comments, there are a couple of things to take
        away from this example:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            If you change an attribute out-param (such as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
            to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code>,
            or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char32_t</span><span class="special">&gt;</span></code>
            to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code>),
            the call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> will often still be
            well-formed.
          </li>
<li class="listitem">
            When changing out a container type, if both containers contain character
            values, the removed container's element type is <code class="computeroutput"><span class="keyword">char32_t</span></code>
            (or <code class="computeroutput"><span class="keyword">wchar_t</span></code> for non-MSVC
            builds), and the new container's element type is <code class="computeroutput"><span class="keyword">char</span></code>
            or <code class="computeroutput"><span class="identifier">char8_t</span></code>, Boost.Parser
            assumes that this is a UTF-32-to-UTF-8 conversion, and silently transcodes
            the data when inserting into the new container.
          </li>
</ul></div>
<p>
        Let's look at a case where another simple-seeming type replacement does
        <span class="bold"><strong>not</strong></span> work. First, the case that works:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="special">-(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">%</span> <span class="char">','</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">result</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"a, b"</span><span class="special">,</span> <span class="identifier">parser</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">,</span> <span class="identifier">result</span><span class="special">);</span>
</pre>
<p>
        <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">parser</span><span class="special">)</span></code>
        is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span></code>. Even though we pass a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code>,
        everything is fine. However, if we modify this case only sightly, so that
        the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span></code> is nested within the attribute, the code
        becomes ill-formed.
      </p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">S</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">chars</span><span class="special">;</span>
    <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="special">-(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">%</span> <span class="char">','</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">;</span>
<span class="identifier">S</span> <span class="identifier">result</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"a, b 42"</span><span class="special">,</span> <span class="identifier">parser</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">,</span> <span class="identifier">result</span><span class="special">);</span>
</pre>
<p>
        If we change <code class="computeroutput"><span class="identifier">chars</span></code> to a
        <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span></code>,
        the code is still ill-formed. Same if we change <code class="computeroutput"><span class="identifier">chars</span></code>
        to a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>. We must actually use <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span></code> exactly to make the code well-formed
        again.
      </p>
<p>
        The reason the same looseness from the top-level parser does not apply to
        a nested parser is that, at some point in the code, the parser <code class="computeroutput"><span class="special">-(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">%</span> <span class="char">','</span><span class="special">)</span></code> would try
        to assign a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span></code> — the element type of the attribute
        type it normally generates — to a <code class="computeroutput"><span class="identifier">chars</span></code>.
        If there's no implicit conversion there, the code is ill-formed.
      </p>
<p>
        The take-away for this last example is that the ability to arbitrarily swap
        out data types within the type of the attribute you pass to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> is very flexible, but is
        also limited to structurally simple cases. When we discuss <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code> in the next section,
        we'll see how this flexibility in the types of attributes can help when writing
        complicated parsers.
      </p>
<p>
        Those were examples of swapping out one container type for another. They
        make good examples because that is more likely to be surprising, and so it's
        getting lots of coverage here. You can also do much simpler things like parse
        using a <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a5a7399c57e54ceedc43f5978ac51618a.html" title="Global uint_">uint_</a></code>,
        and writing its attribute into a <code class="computeroutput"><span class="keyword">double</span></code>.
        In general, you can swap any type <code class="computeroutput"><span class="identifier">T</span></code>
        out of the attribute, as long as the swap would not result in some ill-formed
        assignment within the parse.
      </p>
<p>
        Here is another example that also produces surprising results, for a different
        reason.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'b'</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'c'</span><span class="special">)</span> <span class="special">|</span>
                        <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'x'</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'y'</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'z'</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">str</span> <span class="special">=</span> <span class="string">"abc"</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span> <span class="keyword">char</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;</span> <span class="identifier">chars</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">parser</span><span class="special">,</span> <span class="identifier">chars</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">b</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">chars</span> <span class="special">==</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">(</span><span class="char">'c'</span><span class="special">,</span> <span class="char">'\0'</span><span class="special">,</span> <span class="char">'\0'</span><span class="special">));</span>
</pre>
<p>
        This looks wrong, but is expected behavior. At every stage of the parse that
        produces an attribute, Boost.Parser tries to assign that attribute to some
        part of the out-param attribute provided to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>,
        if there is one. Note that <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">parser</span><span class="special">)</span></code> is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>,
        because each sequence parser is three <code class="computeroutput"><span class="identifier">char_</span></code>
        parsers in a row, which forms a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>;
        there are two such alternatives, so the overall attribute is also <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
        During the parse, when the first parser <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'a'</span><span class="special">)</span></code>
        matches the input, it produces the attribute <code class="computeroutput"><span class="char">'a'</span></code>
        and needs to assign it to its destination. Some logic inside the sequence
        parser indicates that this <code class="computeroutput"><span class="char">'a'</span></code>
        contributes to the value in the <code class="computeroutput"><span class="number">0</span></code>th
        position in the result tuple, if the result is being written into a tuple.
        Here, we passed a <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span> <span class="keyword">char</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;</span></code>,
        so it writes <code class="computeroutput"><span class="char">'a'</span></code> into the first
        element. Each subsequent <code class="computeroutput"><span class="identifier">char_</span></code>
        parser does the same thing, and writes over the first element. If we had
        passed a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> as the out-param instead, the logic
        would have seen that the out-param attribute is a string, and would have
        appended <code class="computeroutput"><span class="char">'a'</span></code> to it. Then each subsequent
        parser would have appended to the string.
      </p>
<p>
        Boost.Parser never looks at the arity of the tuple passed to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> to see if there are too
        many or too few elements in it, compared to the expected attribute for the
        parser. In this case, there are two extra elements that are never touched.
        If there had been too few elements in the tuple, you would have seen a compilation
        error. The reason that Boost.Parser never does this kind of type-checking
        up front is that the loose assignment logic is spread out among the individual
        parsers; the top-level parse can determine what the expected attribute is,
        but not whether a passed attribute of another type is a suitable stand-in.
      </p>
<h5>
<a name="boost_parser.tutorial.the__parse____api.h5"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the__parse____api.compatibility_of__code__phrase_role__identifier__variant__phrase___code__attribute_out_parameters"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api.compatibility_of__code__phrase_role__identifier__variant__phrase___code__attribute_out_parameters">Compatibility
        of <code class="computeroutput"><span class="identifier">variant</span></code> attribute out-parameters</a>
      </h5>
<p>
        The use of a variant in an out-param is compatible if the default attribute
        can be assigned to the <code class="computeroutput"><span class="identifier">variant</span></code>.
        No other work is done to make the assignment compatible. For instance, this
        will work as you'd expect:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">v</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"42"</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">,</span> <span class="identifier">v</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">b</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">index</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">v</span><span class="special">)</span> <span class="special">==</span> <span class="number">42</span><span class="special">);</span>
</pre>
<p>
        Again, this works because <code class="computeroutput"><span class="identifier">v</span> <span class="special">=</span> <span class="number">42</span></code> is well-formed.
        However, other kinds of substitutions will not work. In particular, the
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a></code>
        to aggregate or aggregate to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a></code> transformations will
        not work. Here's an example.
      </p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">key_value</span>
<span class="special">{</span>
    <span class="keyword">int</span> <span class="identifier">key</span><span class="special">;</span>
    <span class="keyword">double</span> <span class="identifier">value</span><span class="special">;</span>
<span class="special">};</span>

<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">key_value</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">kv_or_d</span><span class="special">;</span>
<span class="identifier">key_value</span> <span class="identifier">kv</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"42 13.0"</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span><span class="special">,</span> <span class="identifier">kv</span><span class="special">);</span>      <span class="comment">// Ok.</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"42 13.0"</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span><span class="special">,</span> <span class="identifier">kv_or_d</span><span class="special">);</span> <span class="comment">// Error: ill-formed!</span>
</pre>
<p>
        In this case, it would be easy for Boost.Parser to look at the alternative
        types covered by the variant, and do a conversion. However, there are many
        cases in which there is no obviously correct variant alternative type, or
        in which the user might expect one variant alternative type and get another.
        Consider a couple of cases.
      </p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">i_d</span> <span class="special">{</span> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span> <span class="keyword">double</span> <span class="identifier">d</span><span class="special">;</span> <span class="special">};</span>
<span class="keyword">struct</span> <span class="identifier">d_i</span> <span class="special">{</span> <span class="keyword">double</span> <span class="identifier">d</span><span class="special">;</span> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span> <span class="special">};</span>
<span class="keyword">using</span> <span class="identifier">v1</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">i_d</span><span class="special">,</span> <span class="identifier">d_i</span><span class="special">&gt;;</span>

<span class="keyword">struct</span> <span class="identifier">i_s</span> <span class="special">{</span> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span> <span class="keyword">short</span> <span class="identifier">s</span><span class="special">;</span> <span class="special">};</span>
<span class="keyword">struct</span> <span class="identifier">d_d</span> <span class="special">{</span> <span class="keyword">double</span> <span class="identifier">d1</span><span class="special">;</span> <span class="keyword">double</span> <span class="identifier">d2</span><span class="special">;</span> <span class="special">};</span>
<span class="keyword">using</span> <span class="identifier">v2</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">i_s</span><span class="special">,</span> <span class="identifier">d_d</span><span class="special">&gt;;</span>

<span class="keyword">using</span> <span class="identifier">tup_t</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">short</span><span class="special">,</span> <span class="keyword">short</span><span class="special">&gt;;</span>
</pre>
<p>
        If we have a parser that produces a <code class="computeroutput"><span class="identifier">tup_t</span></code>,
        and we have a <code class="computeroutput"><span class="identifier">v1</span></code> attribute
        out-param, the correct variant alternative type clearly does not exist —
        this case is ambiguous, and anyone can see that neither variant alternative
        is a better match. If we were assigning a <code class="computeroutput"><span class="identifier">tup_t</span></code>
        to <code class="computeroutput"><span class="identifier">v2</span></code>, it's even worse. The
        same ambiguity exists, but to the user, <code class="computeroutput"><span class="identifier">i_s</span></code>
        is clearly "closer" than <code class="computeroutput"><span class="identifier">d_d</span></code>.
      </p>
<p>
        So, Boost.Parser only does assignment. If some parser <code class="computeroutput"><span class="identifier">P</span></code>
        generates a default attribute that is not assignable to a variant alternative
        that you want to assign it to, you can just create a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code> that creates either an
        exact variant alternative type, or the variant itself, and use <code class="computeroutput"><span class="identifier">P</span></code> as your rule's parser.
      </p>
<h5>
<a name="boost_parser.tutorial.the__parse____api.h6"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the__parse____api.unicode_versus_non_unicode_parsing"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api.unicode_versus_non_unicode_parsing">Unicode
        versus non-Unicode parsing</a>
      </h5>
<p>
        A call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> either considers the entire
        input to be in a UTF format (UTF-8, UTF-16, or UTF-32), or it considers the
        entire input to be in some unknown encoding. Here is how it deduces which
        case the call falls under:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            If the range is a sequence of <code class="computeroutput"><span class="identifier">char8_t</span></code>,
            or if the input is a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">utf8_view</span></code>,
            the input is UTF-8.
          </li>
<li class="listitem">
            Otherwise, if the value type of the range is <code class="computeroutput"><span class="keyword">char</span></code>,
            the input is in an unknown encoding.
          </li>
<li class="listitem">
            Otherwise, the input is in a UTF encoding.
          </li>
</ul></div>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
          if you want to want to parse in ASCII-only mode, or in some other non-Unicode
          encoding, use only sequences of <code class="computeroutput"><span class="keyword">char</span></code>,
          like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> or <code class="computeroutput"><span class="keyword">char</span>
          <span class="keyword">const</span> <span class="special">*</span></code>.
        </p></td></tr>
</table></div>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
          If you want to ensure all input is parsed as Unicode, pass the input range
          <code class="computeroutput"><span class="identifier">r</span></code> as <code class="computeroutput"><span class="identifier">r</span>
          <span class="special">|</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">as_utf32</span></code>
          — that's the first thing that happens to it inside <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> in the Unicode parsing
          path anyway.
        </p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          Since passing <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">utfN_view</span></code> is a special case, and since
          a sequence of <code class="computeroutput"><span class="keyword">char</span></code>s <code class="computeroutput"><span class="identifier">r</span></code> is otherwise considered an unknown
          encoding, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">r</span> <span class="special">|</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">as_utf8</span><span class="special">,</span> <span class="identifier">p</span><span class="special">)</span></code> treats
          <code class="computeroutput"><span class="identifier">r</span></code> as UTF-8, whereas <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">r</span><span class="special">,</span> <span class="identifier">p</span><span class="special">)</span></code> does not.
        </p></td></tr>
</table></div>
<h5>
<a name="boost_parser.tutorial.the__parse____api.h7"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the__parse____api.the__code__phrase_role__identifier__trace_mode__phrase___code__parameter_to__functionname_alt__boost__parser__parse___code__phrase_role__identifier__parse__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api.the__code__phrase_role__identifier__trace_mode__phrase___code__parameter_to__functionname_alt__boost__parser__parse___code__phrase_role__identifier__parse__phrase__phrase_role__special______phrase___code___functionname_">The
        <code class="computeroutput"><span class="identifier">trace_mode</span></code> parameter to
        parse()</a>
      </h5>
<p>
        Debugging parsers is notoriously difficult once they reach a certain size.
        To get a verbose trace of your parse, pass <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a70159b38d52d5203b78c0078c2f4e7f6.html" title="Type trace">boost::parser::trace</a><span class="special">::</span><span class="identifier">on</span></code> as the final parameter to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>. It will show you the current
        parser being matched, the next few characters to be parsed, and any attributes
        generated. See the <a class="link" href="tutorial.html#boost_parser.tutorial.error_handling_and_debugging" title="Error Handling and Debugging">Error
        Handling and Debugging</a> section of the tutorial for details.
      </p>
<h5>
<a name="boost_parser.tutorial.the__parse____api.h8"></a>
        <span class="phrase"><a name="boost_parser.tutorial.the__parse____api.globals_and_error_handlers"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api.globals_and_error_handlers">Globals
        and error handlers</a>
      </h5>
<p>
        Each call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> can optionally have a globals
        object associated with it. To use a particular globals object with you parser,
        you call <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a201997f10fbf43e8ee98f3f1904a2869.html" title="Function template with_globals">with_globals()</a></code> to create a new parser with
        the globals object in it:
      </p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">globals_t</span>
<span class="special">{</span>
    <span class="keyword">int</span> <span class="identifier">foo</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">bar</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="comment">/* ... */</span><span class="special">;</span>
<span class="identifier">globals_t</span> <span class="identifier">globals</span><span class="special">{</span><span class="number">42</span><span class="special">,</span> <span class="string">"yay"</span><span class="special">};</span>
<span class="keyword">auto</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"str"</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">with_globals</span><span class="special">(</span><span class="identifier">parser</span><span class="special">,</span> <span class="identifier">globals</span><span class="special">));</span>
</pre>
<p>
        Every semantic action within that call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        can access the same <code class="computeroutput"><span class="identifier">globals_t</span></code>
        object using <code class="computeroutput"><span class="identifier">_globals</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>.
      </p>
<p>
        The default error handler is great for most needs, but if you want to change
        it, you can do so by creating a new parser with a call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aae7cd87f98b93f630715d9f28aff4747.html" title="Function template with_error_handler">with_error_handler()</a></code>:
      </p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="comment">/* ... */</span><span class="special">;</span>
<span class="identifier">my_error_handler</span> <span class="identifier">error_handler</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"str"</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">with_error_handler</span><span class="special">(</span><span class="identifier">parser</span><span class="special">,</span> <span class="identifier">error_handler</span><span class="special">));</span>
</pre>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
          If your parsing environment does not allow you to report errors to a terminal,
          you may want to use <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1callback__error__handler.html" title="Struct callback_error_handler">callback_error_handler</a></code> instead
          of the default error handler.
        </p></td></tr>
</table></div>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          Globals and the error handler are ignored, if present, on any parser except
          the top-level parser.
        </p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.more_about_rules"></a><a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules" title="More About Rules">More About Rules</a>
</h3></div></div></div>
<p>
        In the earlier page about <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code> (<a class="link" href="tutorial.html#boost_parser.tutorial.rule_parsers" title="Rule Parsers">Rule
        Parsers</a>), I described <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code> as being analogous to
        functions. <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>
        are, at base, organizational. Here are the common use cases for <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>.
        Use a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>
        if you want to:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            fix the attribute type produced by a parser to something other than the
            default;
          </li>
<li class="listitem">
            control the attributes generated by adjacent sequence parsers;
          </li>
<li class="listitem">
            create a parser that produces useful diagnostic text;
          </li>
<li class="listitem">
            create a recursive rule (more on this below);
          </li>
<li class="listitem">
            create a set of mutually-recursive parsers;
          </li>
<li class="listitem">
            do callback parsing.
          </li>
</ul></div>
<p>
        Let's look at the use cases in detail.
      </p>
<h5>
<a name="boost_parser.tutorial.more_about_rules.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.more_about_rules.fixing_the_attribute_type"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules.fixing_the_attribute_type">Fixing
        the attribute type</a>
      </h5>
<p>
        We saw in the previous section how <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        is flexible in what types it will accept as attribute out-parameters. Here's
        another example.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="keyword">int</span> <span class="special">%</span> <span class="char">','</span><span class="special">,</span> <span class="identifier">result</span><span class="special">);</span>
</pre>
<p>
        <code class="computeroutput"><span class="identifier">result</span></code> can be one of many
        different types. It could be <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code>.
        It could be <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">set</span><span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">long</span><span class="special">&gt;</span></code>. It could be a lot of things. Often,
        this is a very useful property; if you had to rewrite all of your parser
        logic because you changed the desired container in some part of your attribute
        from a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code> to a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span></code>,
        that would be annoying. However, that flexibility comes at the cost of type
        checking. If you want to write a parser that <span class="bold"><strong>always</strong></span>
        produces exactly a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">&gt;</span></code> <span class="bold"><strong>and no other type</strong></span>,
        you also probably want a compilation error if you accidentally pass that
        parser a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">set</span><span class="special">&lt;</span><span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">&gt;</span></code> attribute instead. There is no way with
        a plain parser to enforce that its attribute type may only ever be a single,
        fixed type.
      </p>
<p>
        Fortunately, <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>
        allow you to write a parser that has a fixed attribute type. Every rule has
        a specific attribute type, provided as a template parameter. If one is not
        specified, the rule has no attribute. The fact that the attribute is a specific
        type allows you to remove attribute flexibility. For instance, say we have
        a rule defined like this:
      </p>
<p>
</p>
<pre class="programlisting"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">doubles</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;&gt;</span> <span class="identifier">doubles</span> <span class="special">=</span> <span class="string">"doubles"</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">doubles_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span> <span class="special">%</span> <span class="char">','</span><span class="special">;</span>
<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">doubles</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        You can then use it in a call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>,
        and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> will return a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;&gt;</span></code>:
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">doubles</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        If you call <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code> with an attribute out-parameter,
        it must be exactly <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span></code>:
      </p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">vec_result</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">doubles</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">,</span> <span class="identifier">vec_result</span><span class="special">);</span> <span class="comment">// Ok.</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">deque_result</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">doubles</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">,</span> <span class="identifier">deque_result</span><span class="special">);</span> <span class="comment">// Ill-formed!</span>
</pre>
<p>
        If we wanted to use a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span></code> as the attribute type of our rule:
      </p>
<pre class="programlisting"><span class="comment">// Attribute changed to std::deque&lt;double&gt;.</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">doubles</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;&gt;</span> <span class="identifier">doubles</span> <span class="special">=</span> <span class="string">"doubles"</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">doubles_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span> <span class="special">%</span> <span class="char">','</span><span class="special">;</span>
<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">doubles</span><span class="special">);</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">deque_result</span><span class="special">;</span>
    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">doubles</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">,</span> <span class="identifier">deque_result</span><span class="special">);</span> <span class="comment">// Ok.</span>
<span class="special">}</span>
</pre>
<p>
        The take-away here is that the attribute flexibility is still available,
        but only <span class="bold"><strong>within</strong></span> the rule — the parser
        <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span> <span class="special">%</span> <span class="char">','</span></code> can parse into a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span></code> or a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span></code>, but the rule <code class="computeroutput"><span class="identifier">doubles</span></code>
        must parse into only the exact attribute it was declared to generate.
      </p>
<p>
        The reason for this is that, inside the rule parsing implementation, there
        is code something like this:
      </p>
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">attr_t</span> <span class="special">=</span> <span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">doubles_def</span><span class="special">);</span>
<span class="identifier">attr_t</span> <span class="identifier">attr</span><span class="special">;</span>
<span class="identifier">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">parser</span><span class="special">,</span> <span class="identifier">attr</span><span class="special">);</span>
<span class="identifier">attribute_out_param</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">attr</span><span class="special">);</span>
</pre>
<p>
        Where <code class="computeroutput"><span class="identifier">attribute_out_param</span></code>
        is the attribute out-parameter we pass to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>.
        If that final move assignment is ill-formed, the call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        is too.
      </p>
<p>
        You can also use rules to exploit attribute flexibility. Even though a rule
        reduces the flexibility of attributes it can generate, the fact that it is
        so easy to write a new rule means that we can use rules themselves to get
        the attribute flexibility we want across our code:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="comment">// We only need to write the definition once...</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">generic_doubles_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span> <span class="special">%</span> <span class="char">','</span><span class="special">;</span>

<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">vec_doubles</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;&gt;</span> <span class="identifier">vec_doubles</span> <span class="special">=</span> <span class="string">"vec_doubles"</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">vec_doubles_def</span> <span class="special">=</span> <span class="identifier">generic_doubles_def</span><span class="special">;</span> <span class="comment">// ... and re-use it,</span>
<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">vec_doubles</span><span class="special">);</span>

<span class="comment">// Attribute changed to std::deque&lt;double&gt;.</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">deque_doubles</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;&gt;</span> <span class="identifier">deque_doubles</span> <span class="special">=</span> <span class="string">"deque_doubles"</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">deque_doubles_def</span> <span class="special">=</span> <span class="identifier">generic_doubles_def</span><span class="special">;</span> <span class="comment">// ... and re-use it again.</span>
<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">deque_doubles</span><span class="special">);</span>
</pre>
<p>
        Now we have one of each, and we did not have to copy any parsing logic that
        would have to be maintained in two places.
      </p>
<p>
        Sometimes, you need to create a rule to enforce a certain attribute type,
        but the rule's attribute is not constructible from its parser's attribute.
        When that happens, you'll need to write a semantic action.
      </p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">type_t</span>
<span class="special">{</span>
    <span class="identifier">type_t</span><span class="special">()</span> <span class="special">=</span> <span class="keyword">default</span><span class="special">;</span>
    <span class="keyword">explicit</span> <span class="identifier">type_t</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">x_</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">{}</span>
    <span class="comment">// etc.</span>

    <span class="keyword">double</span> <span class="identifier">x_</span><span class="special">;</span>
<span class="special">};</span>

<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="keyword">auto</span> <span class="identifier">doubles_to_type</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span>
    <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
    <span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">type_t</span><span class="special">(</span><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)[</span><span class="number">0</span><span class="identifier">_c</span><span class="special">]</span> <span class="special">*</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)[</span><span class="number">1</span><span class="identifier">_c</span><span class="special">]);</span>
<span class="special">};</span>

<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">type_tag</span><span class="special">,</span> <span class="identifier">type_t</span><span class="special">&gt;</span> <span class="identifier">type</span> <span class="special">=</span> <span class="string">"type"</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">type_def</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span><span class="special">)[</span><span class="identifier">doubles_to_type</span><span class="special">];</span>
<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">type</span><span class="special">);</span>
</pre>
<p>
        For a rule <code class="computeroutput"><span class="identifier">R</span></code> and its parser
        <code class="computeroutput"><span class="identifier">P</span></code>, we do not need to write
        such a semantic action if:
      </p>
<p>
        - <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">R</span><span class="special">)</span></code> is an
        aggregate, and <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">P</span><span class="special">)</span></code>
        is a compatible tuple;
      </p>
<p>
        - <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">R</span><span class="special">)</span></code> is a
        tuple, and <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">P</span><span class="special">)</span></code> is a
        compatible aggregate;
      </p>
<p>
        - <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">R</span><span class="special">)</span></code> is a
        non-aggregate class type <code class="computeroutput"><span class="identifier">C</span></code>,
        and <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">P</span><span class="special">)</span></code> is a
        tuple whose elements can be used to construct <code class="computeroutput"><span class="identifier">C</span></code>;
        or
      </p>
<p>
        - <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">R</span><span class="special">)</span></code> and
        <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span><span class="special">(</span><span class="identifier">P</span><span class="special">)</span></code> are
        compatible types.
      </p>
<p>
        The notion of "compatible" is defined in <a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api" title="The parse() API">The
        <code class="computeroutput"><span class="identifier">parse</span><span class="special">()</span></code>
        API</a>.
      </p>
<h5>
<a name="boost_parser.tutorial.more_about_rules.h1"></a>
        <span class="phrase"><a name="boost_parser.tutorial.more_about_rules.controlling_the_attributes_generated"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules.controlling_the_attributes_generated">Controlling
        the attributes generated</a>
      </h5>
<p>
        See the <a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation.a_sequence_parser_attribute_example">A
        sequence parser attribute example</a> in the <a class="link" href="tutorial.html#boost_parser.tutorial.attribute_generation" title="Attribute Generation">Attribute
        Generation</a> section for details.
      </p>
<h5>
<a name="boost_parser.tutorial.more_about_rules.h2"></a>
        <span class="phrase"><a name="boost_parser.tutorial.more_about_rules.creating_a_parser_for_better_diagnostics"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules.creating_a_parser_for_better_diagnostics">Creating
        a parser for better diagnostics</a>
      </h5>
<p>
        Each <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>
        has associated diagnostic text that Boost.Parser can use for failures of
        that rule. This is useful when the parse reaches a parse failure at an expectation
        point (see <a class="link" href="tutorial.html#boost_parser.tutorial.backtracking.expectation_points">Expectation
        points</a>). Let's say you have the following code defined somewhere.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">value_tag</span><span class="special">&gt;</span> <span class="identifier">value</span> <span class="special">=</span>
    <span class="string">"an integer, or a list of integers in braces"</span><span class="special">;</span>

<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">ints</span> <span class="special">=</span> <span class="char">'{'</span> <span class="special">&gt;</span> <span class="special">(</span><span class="identifier">value</span> <span class="special">%</span> <span class="char">','</span><span class="special">)</span> <span class="special">&gt;</span> <span class="char">'}'</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">value_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">|</span> <span class="identifier">ints</span><span class="special">;</span>

<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">value</span><span class="special">);</span>
</pre>
<p>
        Notice the two expectation points. One before <code class="computeroutput"><span class="special">(</span><span class="identifier">value</span> <span class="special">%</span> <span class="char">','</span><span class="special">)</span></code>, one before
        the final <code class="computeroutput"><span class="char">'}'</span></code>. Later, you call
        parse in some input:
      </p>
<pre class="programlisting"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"{ 4, 5 a"</span><span class="special">,</span> <span class="identifier">value</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
</pre>
<p>
        This runs should of the second expectation point, and produces output like
        this:
      </p>
<pre class="programlisting">1:7: error: Expected '}' here:
{ 4, 5 a
       ^
</pre>
<p>
        That's a pretty good error message. Here's what it looks like if we violate
        the earlier expectation:
      </p>
<pre class="programlisting"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"{ }"</span><span class="special">,</span> <span class="identifier">value</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
</pre>
<pre class="programlisting">1:2: error: Expected an integer, or a list of integers in braces % ',' here:
{ }
  ^
</pre>
<p>
        Not nearly as nice. The problem is that the expectation is on <code class="computeroutput"><span class="special">(</span><span class="identifier">value</span> <span class="special">%</span> <span class="char">','</span><span class="special">)</span></code>.
        So, even thought we gave <code class="computeroutput"><span class="identifier">value</span></code>
        reasonable dianostic text, we put the text on the wrong thing. We can introduce
        a new rule to put the diagnstic text in the right place.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">value_tag</span><span class="special">&gt;</span> <span class="identifier">value</span> <span class="special">=</span>
    <span class="string">"an integer, or a list of integers in braces"</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">comma_values_tag</span><span class="special">&gt;</span> <span class="identifier">comma_values</span> <span class="special">=</span>
    <span class="string">"a comma-delimited list of integers"</span><span class="special">;</span>

<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">ints</span> <span class="special">=</span> <span class="char">'{'</span> <span class="special">&gt;</span> <span class="identifier">comma_values</span> <span class="special">&gt;</span> <span class="char">'}'</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">value_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">|</span> <span class="identifier">ints</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">comma_values_def</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">value</span> <span class="special">%</span> <span class="char">','</span><span class="special">);</span>

<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">value</span><span class="special">,</span> <span class="identifier">comma_values</span><span class="special">);</span>
</pre>
<p>
        Now when we call <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"{ }"</span><span class="special">,</span>
        <span class="identifier">value</span><span class="special">,</span>
        <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">)</span></code> we
        get a much better message:
      </p>
<pre class="programlisting">1:2: error: Expected a comma-delimited list of integers here:
{ }
  ^
</pre>
<p>
        The <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>
        <code class="computeroutput"><span class="identifier">value</span></code> might be useful elsewhere
        in our code, perhaps in another parser. It's diagnostic text is appropriate
        for those other potential uses.
      </p>
<h5>
<a name="boost_parser.tutorial.more_about_rules.h3"></a>
        <span class="phrase"><a name="boost_parser.tutorial.more_about_rules.recursive_rules"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules.recursive_rules">Recursive
        rules</a>
      </h5>
<p>
        It's pretty common to see grammars that include recursive rules. Consider
        this EBNF rule for balanced parentheses:
      </p>
<pre class="programlisting">&lt;parens&gt; ::= "" | ( "(" &lt;parens&gt; ")" )
</pre>
<p>
        We can try to write this using Boost.Parser like this:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parens</span> <span class="special">=</span> <span class="char">'('</span> <span class="special">&gt;&gt;</span> <span class="identifier">parens</span> <span class="special">&gt;&gt;</span> <span class="char">')'</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">eps</span><span class="special">;</span>
</pre>
<p>
        We had to put the <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">eps</span></code> second, because Boost.Parser's parsing
        algorithm is greedy. Otherwise, it's just a straight transliteration. Unfortunately,
        it does not work. The code is ill-formed because you can't define a variable
        in terms of itself. Well you can, but nothing good comes of it. If we instead
        make the parser in terms of a forward-declared <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>, it works.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">parens_tag</span><span class="special">&gt;</span> <span class="identifier">parens</span> <span class="special">=</span> <span class="string">"matched parentheses"</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">parens_def</span> <span class="special">=</span> <span class="char">'('</span> <span class="special">&gt;&gt;</span> <span class="identifier">parens</span> <span class="special">&gt;</span> <span class="char">')'</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">eps</span><span class="special">;</span>
<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">parens</span><span class="special">);</span>
</pre>
<p>
        Later, if we use it to parse, it does what we want.
      </p>
<pre class="programlisting"><span class="identifier">assert</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"(((())))"</span><span class="special">,</span> <span class="identifier">parens</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">));</span>
</pre>
<p>
        When it fails, it even produces nice diagnostics.
      </p>
<pre class="programlisting"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"(((()))"</span><span class="special">,</span> <span class="identifier">parens</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
</pre>
<pre class="programlisting">1:7: error: Expected ')' here (end of input):
(((()))
       ^
</pre>
<p>
        Recursive <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>
        work differently from other parsers in one way: when re-entering the rule
        recursively, only the attribute variable (<code class="computeroutput"><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>
        in your semantic actions) is unique to that instance of the rule. All the
        other state of the uppermost instance of that rule is shared. This includes
        the value of the rule (<code class="computeroutput"><span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>),
        and the locals and parameters to the rule. In other words, <code class="computeroutput"><span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code> returns a reference to the <span class="bold"><strong>same
        object</strong></span> in every instance of a recursive <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>. This is because each
        instance of the rule needs a place to put the attribute it generates from
        its parse. However, we only want a single return value for the uppermost
        rule; if each instance had a separate value in <code class="computeroutput"><span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>,
        then it would be impossible to build up the result of a recursive rule step
        by step during in the evaluation of the recursive instantiations.
      </p>
<p>
        Also, consider this rule:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">ints_tag</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;&gt;</span> <span class="identifier">ints</span> <span class="special">=</span> <span class="string">"ints"</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">ints_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="identifier">ints</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">eps</span><span class="special">;</span>
</pre>
<p>
        What is the default attribute type for ints_def? It sure looks like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;&gt;</span></code>.
        Inside the evaluation of <code class="computeroutput"><span class="identifier">ints</span></code>,
        Boost.Parser must evaluate <code class="computeroutput"><span class="identifier">ints_def</span></code>,
        and then produce a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code> —
        the return type of <code class="computeroutput"><span class="identifier">ints</span></code> —
        from it. How? How do you turn a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;&gt;</span></code>
        into a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code>? To
        a human, it seems obvious, but the metaprogramming that properly handles
        this simple example and the general case is certainly beyond me.
      </p>
<p>
        Boost.Parser has a specific semantic for what consitutes a recursive rule.
        Each rule has a tag type associated with it, and if Boost.Parser enters a
        rule with a certain tag <code class="computeroutput"><span class="identifier">Tag</span></code>,
        and the currently-evaluating rule (if there is one) also has the tag <code class="computeroutput"><span class="identifier">Tag</span></code>, then rule instance being entered is
        considered to be a recursion. No other situations are considered recursion.
        In particular, if you have rules <code class="computeroutput"><span class="identifier">Ra</span></code>
        and <code class="computeroutput"><span class="identifier">Rb</span></code>, and <code class="computeroutput"><span class="identifier">Ra</span></code> uses <code class="computeroutput"><span class="identifier">Rb</span></code>,
        which in turn used <code class="computeroutput"><span class="identifier">Ra</span></code>, the
        second use of <code class="computeroutput"><span class="identifier">Ra</span></code> is not considered
        recursion. <code class="computeroutput"><span class="identifier">Ra</span></code> and <code class="computeroutput"><span class="identifier">Rb</span></code> are of course mutually recursive, but
        neither is considered a "recursive rule" for purposes of getting
        a unique value, locals, and parameters.
      </p>
<h5>
<a name="boost_parser.tutorial.more_about_rules.h4"></a>
        <span class="phrase"><a name="boost_parser.tutorial.more_about_rules.mutually_recursive_rules"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules.mutually_recursive_rules">Mutually-recursive
        rules</a>
      </h5>
<p>
        One of the advantages of using rules is that you can declare all your rules
        up front and then use them immediately afterward. This lets you make rules
        that use each other without introducing cycles:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="comment">// Assume we have some polymorphic type that can be an object/dictionary,</span>
<span class="comment">// array, string, or int, called `value_type`.</span>

<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">string</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">string</span> <span class="special">=</span> <span class="string">"string"</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">object_element</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">value_type</span><span class="special">&gt;&gt;</span> <span class="keyword">const</span> <span class="identifier">object_element</span> <span class="special">=</span> <span class="string">"object-element"</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">object</span><span class="special">,</span> <span class="identifier">value_type</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">object</span> <span class="special">=</span> <span class="string">"object"</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">array</span><span class="special">,</span> <span class="identifier">value_type</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">array</span> <span class="special">=</span> <span class="string">"array"</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">value_tag</span><span class="special">,</span> <span class="identifier">value_type</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">value</span> <span class="special">=</span> <span class="string">"value"</span><span class="special">;</span>

<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">string_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">[</span><span class="char">'"'</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span><span class="special">)</span> <span class="special">&gt;</span> <span class="char">'"'</span><span class="special">];</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">object_element_def</span> <span class="special">=</span> <span class="identifier">string</span> <span class="special">&gt;</span> <span class="char">':'</span> <span class="special">&gt;</span> <span class="identifier">value</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">object_def</span> <span class="special">=</span> <span class="char">'{'</span><span class="identifier">_l</span> <span class="special">&gt;&gt;</span> <span class="special">-(</span><span class="identifier">object_element</span> <span class="special">%</span> <span class="char">','</span><span class="special">)</span> <span class="special">&gt;</span> <span class="char">'}'</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">array_def</span> <span class="special">=</span> <span class="char">'['</span><span class="identifier">_l</span> <span class="special">&gt;&gt;</span> <span class="special">-(</span><span class="identifier">value</span> <span class="special">%</span> <span class="char">','</span><span class="special">)</span> <span class="special">&gt;</span> <span class="char">']'</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">value_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">bool_</span> <span class="special">|</span> <span class="identifier">string</span> <span class="special">|</span> <span class="identifier">array</span> <span class="special">|</span> <span class="identifier">object</span><span class="special">;</span>

<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">object_element</span><span class="special">,</span> <span class="identifier">object</span><span class="special">,</span> <span class="identifier">array</span><span class="special">,</span> <span class="identifier">value</span><span class="special">);</span>
</pre>
<p>
        Here we have a parser for a Javascript-value-like type <code class="computeroutput"><span class="identifier">value_type</span></code>.
        <code class="computeroutput"><span class="identifier">value_type</span></code> may be an array,
        which itself may contain other arrays, objects, strings, etc. Since we need
        to be able to parse objects within arrays and vice versa, we need each of
        those two parsers to be able to refer to each other.
      </p>
<h5>
<a name="boost_parser.tutorial.more_about_rules.h5"></a>
        <span class="phrase"><a name="boost_parser.tutorial.more_about_rules.callback_parsing"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules.callback_parsing">Callback
        parsing</a>
      </h5>
<p>
        Only <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>
        can be callback parsers, so if you want to get attributes supplied to you
        via callbacks instead of somewhere in the middle of a giant attribute that
        represents the whole parse result, you need to use <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>. See <a class="link" href="extended_examples.html#boost_parser.extended_examples.parsing_json_with_callbacks" title="Parsing JSON With Callbacks">Parsing
        JSON With Callbacks</a> for an extended example of callback parsing.
      </p>
<h5>
<a name="boost_parser.tutorial.more_about_rules.h6"></a>
        <span class="phrase"><a name="boost_parser.tutorial.more_about_rules.accessors_available_in_semantic_actions_on_rules"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules.accessors_available_in_semantic_actions_on_rules">Accessors
        available in semantic actions on rules</a>
      </h5>
<h5>
<a name="boost_parser.tutorial.more_about_rules.h7"></a>
        <span class="phrase"><a name="boost_parser.tutorial.more_about_rules._functionname_alt__boost__parser___val___code__phrase_role__identifier___val__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules._functionname_alt__boost__parser___val___code__phrase_role__identifier___val__phrase__phrase_role__special______phrase___code___functionname_">_val()</a>
      </h5>
<p>
        Inside all of a rule's semantic actions, the expression <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3786fbbcb7262b8da0b87e7ac30e37.html" title="Function _val">_val</a><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>
        is a reference to the attribute that the rule generates. This can be useful
        when you want subparsers to build up the attribute in a specific way:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>

<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ints</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;&gt;</span> <span class="keyword">const</span> <span class="identifier">ints</span> <span class="special">=</span> <span class="string">"ints"</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">twenty_zeros</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">).</span><span class="identifier">resize</span><span class="special">(</span><span class="number">20</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span> <span class="special">};</span>
<span class="keyword">auto</span> <span class="identifier">push_back</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">).</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">));</span> <span class="special">};</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">ints_def</span> <span class="special">=</span> <span class="string">"20-zeros"</span><span class="identifier">_l</span><span class="special">[</span><span class="identifier">twenty_zeros</span><span class="special">]</span> <span class="special">|</span> <span class="special">+</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">[</span><span class="identifier">push_back</span><span class="special">];</span>
<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">ints</span><span class="special">);</span>
</pre>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
          That's just an example. It's almost always better to do things without
          using semantic actions. We could have instead written <code class="computeroutput"><span class="identifier">ints_def</span></code>
          as <code class="computeroutput"><span class="string">"20-zeros"</span> <span class="special">&gt;&gt;</span>
          <span class="identifier">bp</span><span class="special">::</span><span class="identifier">attr</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="number">20</span><span class="special">))</span> <span class="special">|</span>
          <span class="special">+</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span></code>,
          which has the same semantics, is a lot easier to read, and is a lot less
          code.
        </p></td></tr>
</table></div>
<h5>
<a name="boost_parser.tutorial.more_about_rules.h8"></a>
        <span class="phrase"><a name="boost_parser.tutorial.more_about_rules.locals"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules.locals">Locals</a>
      </h5>
<p>
        The <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>
        template takes another template parameter we have not discussed yet. You
        can pass a third parameter <code class="computeroutput"><span class="identifier">LocalState</span></code>
        to <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>,
        which will be defaulted csontructed by the <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>, and made available within
        semantic actions used in the rule as <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aea9a85108e6af1280eccd9135584938d.html" title="Function template _locals">_locals</a><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>. This
        gives your rule some local state, if it needs it. The type of <code class="computeroutput"><span class="identifier">LocalState</span></code> can be anything regular. It
        could be a single value, a struct containing multiple values, or a tuple,
        among others.
      </p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">foo_locals</span>
<span class="special">{</span>
    <span class="keyword">char</span> <span class="identifier">first_value</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="special">};</span>

<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">foo</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="identifier">foo_locals</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">foo</span> <span class="special">=</span> <span class="string">"foo"</span><span class="special">;</span>

<span class="keyword">auto</span> <span class="identifier">record_first</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">_locals</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">).</span><span class="identifier">first_value</span> <span class="special">=</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">);</span> <span class="special">}</span>
<span class="keyword">auto</span> <span class="identifier">check_against_first</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span>
    <span class="keyword">char</span> <span class="keyword">const</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">_locals</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">).</span><span class="identifier">first_value</span><span class="special">;</span>
    <span class="keyword">char</span> <span class="keyword">const</span> <span class="identifier">attr</span> <span class="special">=</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">);</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">attr</span> <span class="special">==</span> <span class="identifier">first</span><span class="special">)</span>
        <span class="identifier">_pass</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
    <span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">=</span> <span class="special">(</span><span class="keyword">int</span><span class="special">(</span><span class="identifier">first</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="number">8</span><span class="special">)</span> <span class="special">|</span> <span class="keyword">int</span><span class="special">(</span><span class="identifier">attr</span><span class="special">);</span>
<span class="special">};</span>

<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">foo_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">cu</span><span class="special">[</span><span class="identifier">record_first</span><span class="special">]</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">cu</span><span class="special">[</span><span class="identifier">check_against_first</span><span class="special">];</span>
<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span><span class="identifier">foo</span><span class="special">);</span>
</pre>
<p>
        <code class="computeroutput"><span class="identifier">foo</span></code> matches the input if
        it can match two elements of the input in a row, but only if they are not
        the same value. Without locals, it's a lot harder to write parsers that have
        to track state as they parse.
      </p>
<h5>
<a name="boost_parser.tutorial.more_about_rules.h9"></a>
        <span class="phrase"><a name="boost_parser.tutorial.more_about_rules.parameters"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules.parameters">Parameters</a>
      </h5>
<p>
        Sometimes, it is convenient to parameterize parsers. Consider these parsing
        rules from the <a href="https://yaml.org/spec/1.2/spec.html" target="_top">YAML 1.2</a>
        spec:
      </p>
<pre class="programlisting">[80]
s-separate(n,BLOCK-OUT) ::= s-separate-lines(n)
s-separate(n,BLOCK-IN)  ::= s-separate-lines(n)
s-separate(n,FLOW-OUT)  ::= s-separate-lines(n)
s-separate(n,FLOW-IN)   ::= s-separate-lines(n)
s-separate(n,BLOCK-KEY) ::= s-separate-in-line
s-separate(n,FLOW-KEY)  ::= s-separate-in-line

[136]
in-flow(n,FLOW-OUT)  ::= ns-s-flow-seq-entries(n,FLOW-IN)
in-flow(n,FLOW-IN)   ::= ns-s-flow-seq-entries(n,FLOW-IN)
in-flow(n,BLOCK-KEY) ::= ns-s-flow-seq-entries(n,FLOW-KEY)
in-flow(n,FLOW-KEY)  ::= ns-s-flow-seq-entries(n,FLOW-KEY)

[137]
c-flow-sequence(n,c) ::= “[” s-separate(n,c)? in-flow(c)? “]”

</pre>
<p>
        YAML [137] says that the parsing should proceed into two YAML subrules, both
        of which have these <code class="computeroutput"><span class="identifier">n</span></code> and
        <code class="computeroutput"><span class="identifier">c</span></code> parameters. It is certainly
        possible to transliterate these YAML parsing rules to something that uses
        unparameterized Boost.Parser <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>, but it is quite painful
        to do so. It is better to use a parameterized rule.
      </p>
<p>
        You give parameters to a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code> by calling its <code class="computeroutput"><span class="identifier">with</span><span class="special">()</span></code>
        member. The values you pass to <code class="computeroutput"><span class="identifier">with</span><span class="special">()</span></code> are used to create a <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a></code> that is available in
        semantic actions attached to the rule, using <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a376d70158bb5f8ce13cfcee77bbce958.html" title="Function template _params">_params</a><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>.
      </p>
<p>
        Passing parameters to <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code> like this allows you
        to easily write parsers that change the way they parse depending on contextual
        data that they have already parsed.
      </p>
<p>
        Here is an implementation of YAML [137]. It also implements the two YAML
        rules used directly by [137], rules [136] and [80]. The rules that <span class="bold"><strong>those</strong></span> rules use are also represented below, but are
        implemented using only <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>, so that I don't have
        to repeat too much of the (very large) YAML spec.
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="comment">// A type to represent the YAML parse context.</span>
<span class="keyword">enum</span> <span class="keyword">class</span> <span class="identifier">context</span> <span class="special">{</span>
    <span class="identifier">block_in</span><span class="special">,</span>
    <span class="identifier">block_out</span><span class="special">,</span>
    <span class="identifier">block_key</span><span class="special">,</span>
    <span class="identifier">flow_in</span><span class="special">,</span>
    <span class="identifier">flow_out</span><span class="special">,</span>
    <span class="identifier">flow_key</span>
<span class="special">};</span>

<span class="comment">// A YAML value; no need to fill it in for this example.</span>
<span class="keyword">struct</span> <span class="identifier">value</span>
<span class="special">{</span>
    <span class="comment">// ...</span>
<span class="special">};</span>

<span class="comment">// YAML [66], just stubbed in here.</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">s_separate_in_line</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">eps</span><span class="special">;</span>

<span class="comment">// YAML [137].</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">c_flow_seq_tag</span><span class="special">,</span> <span class="identifier">value</span><span class="special">&gt;</span> <span class="identifier">c_flow_sequence</span> <span class="special">=</span> <span class="string">"c-flow-sequence"</span><span class="special">;</span>
<span class="comment">// YAML [80].</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">s_separate_tag</span><span class="special">&gt;</span> <span class="identifier">s_separate</span> <span class="special">=</span> <span class="string">"s-separate"</span><span class="special">;</span>
<span class="comment">// YAML [136].</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">in_flow_tag</span><span class="special">,</span> <span class="identifier">value</span><span class="special">&gt;</span> <span class="identifier">in_flow</span> <span class="special">=</span> <span class="string">"in-flow"</span><span class="special">;</span>
<span class="comment">// YAML [138]; just eps below.</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">ns_s_flow_seq_entries_tag</span><span class="special">,</span> <span class="identifier">value</span><span class="special">&gt;</span> <span class="identifier">ns_s_flow_seq_entries</span> <span class="special">=</span>
    <span class="string">"ns-s-flow-seq-entries"</span><span class="special">;</span>
<span class="comment">// YAML [81]; just eps below.</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">s_separate_lines_tag</span><span class="special">&gt;</span> <span class="identifier">s_separate_lines</span> <span class="special">=</span> <span class="string">"s-separate-lines"</span><span class="special">;</span>

<span class="comment">// Parser for YAML [137].</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">c_flow_sequence_def</span> <span class="special">=</span>
    <span class="char">'['</span> <span class="special">&gt;&gt;</span>
    <span class="special">-</span><span class="identifier">s_separate</span><span class="special">.</span><span class="identifier">with</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;)</span> <span class="special">&gt;&gt;</span>
    <span class="special">-</span><span class="identifier">in_flow</span><span class="special">.</span><span class="identifier">with</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;)</span> <span class="special">&gt;&gt;</span>
    <span class="char">']'</span><span class="special">;</span>
<span class="comment">// Parser for YAML [80].</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">s_separate_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">switch_</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;)</span>
    <span class="special">(</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">block_out</span><span class="special">,</span> <span class="identifier">s_separate_lines</span><span class="special">.</span><span class="identifier">with</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;))</span>
    <span class="special">(</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">block_in</span><span class="special">,</span> <span class="identifier">s_separate_lines</span><span class="special">.</span><span class="identifier">with</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;))</span>
    <span class="special">(</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">flow_out</span><span class="special">,</span> <span class="identifier">s_separate_lines</span><span class="special">.</span><span class="identifier">with</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;))</span>
    <span class="special">(</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">flow_in</span><span class="special">,</span> <span class="identifier">s_separate_lines</span><span class="special">.</span><span class="identifier">with</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;))</span>
    <span class="special">(</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">block_key</span><span class="special">,</span> <span class="identifier">s_separate_in_line</span><span class="special">)</span>
    <span class="special">(</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">flow_key</span><span class="special">,</span> <span class="identifier">s_separate_in_line</span><span class="special">);</span>
<span class="comment">// Parser for YAML [136].</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">in_flow_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">switch_</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;)</span>
    <span class="special">(</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">flow_out</span><span class="special">,</span> <span class="identifier">ns_s_flow_seq_entries</span><span class="special">.</span><span class="identifier">with</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;,</span> <span class="identifier">context</span><span class="special">::</span><span class="identifier">flow_in</span><span class="special">))</span>
    <span class="special">(</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">flow_in</span><span class="special">,</span> <span class="identifier">ns_s_flow_seq_entries</span><span class="special">.</span><span class="identifier">with</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;,</span> <span class="identifier">context</span><span class="special">::</span><span class="identifier">flow_in</span><span class="special">))</span>
    <span class="special">(</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">block_out</span><span class="special">,</span> <span class="identifier">ns_s_flow_seq_entries</span><span class="special">.</span><span class="identifier">with</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;,</span> <span class="identifier">context</span><span class="special">::</span><span class="identifier">flow_key</span><span class="special">))</span>
    <span class="special">(</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">flow_key</span><span class="special">,</span> <span class="identifier">ns_s_flow_seq_entries</span><span class="special">.</span><span class="identifier">with</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;,</span> <span class="identifier">context</span><span class="special">::</span><span class="identifier">flow_key</span><span class="special">));</span>

<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">ns_s_flow_seq_entries_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">eps</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">s_separate_lines_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">eps</span><span class="special">;</span>

<span class="identifier">BOOST_PARSER_DEFINE_RULES</span><span class="special">(</span>
    <span class="identifier">c_flow_sequence</span><span class="special">,</span>
    <span class="identifier">s_separate</span><span class="special">,</span>
    <span class="identifier">in_flow</span><span class="special">,</span>
    <span class="identifier">ns_s_flow_seq_entries</span><span class="special">,</span>
    <span class="identifier">s_separate_lines</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        YAML [137] (<code class="computeroutput"><span class="identifier">c_flow_sequence</span></code>)
        parses a list. The list may be empty, and must be surrounded by brackets,
        as you see here. But, depending on the current YAML context (the <code class="computeroutput"><span class="identifier">c</span></code> parameter to [137]), we may require certain
        spacing to be matched by <code class="computeroutput"><span class="identifier">s</span><span class="special">-</span><span class="identifier">separate</span></code>,
        and how sub-parser <code class="computeroutput"><span class="identifier">in</span><span class="special">-</span><span class="identifier">flow</span></code> behaves also depends on the current
        context.
      </p>
<p>
        In <code class="computeroutput"><span class="identifier">s_separate</span></code> above, we parse
        differently based on the value of <code class="computeroutput"><span class="identifier">c</span></code>.
        This is done above by using the value of the second parameter to <code class="computeroutput"><span class="identifier">s_separate</span></code> in a switch-parser. The second
        parameter is looked up by using <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a799d01af5dbc14892c557552f26721e1.html" title="Global _p">_p</a></code> as a parse argument.
      </p>
<p>
        <code class="computeroutput"><span class="identifier">in_flow</span></code> does something similar.
        Note that <code class="computeroutput"><span class="identifier">in_flow</span></code> calls its
        subrule by passing its first parameter, but using a fixed value for the second
        value. <code class="computeroutput"><span class="identifier">s_separate</span></code> only passes
        its <code class="computeroutput"><span class="identifier">n</span></code> parameter conditionally.
        The point is that a rule can be used with and without <code class="computeroutput"><span class="special">.</span><span class="identifier">with</span><span class="special">()</span></code>,
        and that you can pass constants or parse arguments to <code class="computeroutput"><span class="special">.</span><span class="identifier">with</span><span class="special">()</span></code>.
      </p>
<p>
        With those rules defined, we could write a unit test for YAML [137] like
        this:
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">test_parser</span> <span class="special">=</span> <span class="identifier">c_flow_sequence</span><span class="special">.</span><span class="identifier">with</span><span class="special">(</span><span class="number">4</span><span class="special">,</span> <span class="identifier">context</span><span class="special">::</span><span class="identifier">block_out</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="string">"[]"</span><span class="special">,</span> <span class="identifier">test_parser</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">result</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        You could extend this with tests for different values of <code class="computeroutput"><span class="identifier">n</span></code>
        and <code class="computeroutput"><span class="identifier">c</span></code>. Obviously, in real
        tests, you parse actual contents inside the <code class="computeroutput"><span class="string">"[]"</span></code>,
        if the other rules were implemented, like [138].
      </p>
<h5>
<a name="boost_parser.tutorial.more_about_rules.h10"></a>
        <span class="phrase"><a name="boost_parser.tutorial.more_about_rules.the__globalname_alt__boost__parser___p___code__phrase_role__identifier___p__phrase___code___globalname__variable_template"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules.the__globalname_alt__boost__parser___p___code__phrase_role__identifier___p__phrase___code___globalname__variable_template">The
        _p
        variable template</a>
      </h5>
<p>
        Getting at one of a rule's arguments and passing it as an argument to another
        parser can be very verbose. <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a799d01af5dbc14892c557552f26721e1.html" title="Global _p">_p</a></code> is a variable template
        that allows you to refer to the <code class="computeroutput"><span class="identifier">n</span></code>th
        argument to the current rule, so that you can, in turn, pass it to one of
        the rule's subparsers. Using this, <code class="computeroutput"><span class="identifier">foo_def</span></code>
        above can be rewritten as:
      </p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">foo_def</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">repeat</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">_p</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;)[</span><span class="char">' '</span><span class="identifier">_l</span><span class="special">];</span>
</pre>
<p>
        Using <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a799d01af5dbc14892c557552f26721e1.html" title="Global _p">_p</a></code>
        can prevent you from having to write a bunch of lambdas that get each get
        an argument out of the parse context using <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a376d70158bb5f8ce13cfcee77bbce958.html" title="Function template _params">_params</a><span class="special">(</span><span class="identifier">ctx</span><span class="special">)[</span><span class="number">0</span><span class="identifier">_c</span><span class="special">]</span></code> or
        similar.
      </p>
<p>
        Note that <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a799d01af5dbc14892c557552f26721e1.html" title="Global _p">_p</a></code>
        is a parse argument (see <a class="link" href="tutorial.html#boost_parser.tutorial.the_parsers_and_their_uses" title="The Parsers And Their Uses">The
        Parsers And Their Uses</a>), meaning that it is an invocable that takes
        the context as its only parameter. If you want to use it inside a semantic
        action, you have to call it.
      </p>
<h5>
<a name="boost_parser.tutorial.more_about_rules.h11"></a>
        <span class="phrase"><a name="boost_parser.tutorial.more_about_rules.special_forms_of_semantic_actions_usable_within_a_rule"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.more_about_rules.special_forms_of_semantic_actions_usable_within_a_rule">Special
        forms of semantic actions usable within a rule</a>
      </h5>
<p>
        Semantic actions in this tutorial are usually of the signature <code class="computeroutput"><span class="keyword">void</span> <span class="special">(</span><span class="keyword">auto</span>
        <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span></code>. That is, they take a context by reference,
        and return nothing. If they were to return something, that something would
        just get dropped on the floor.
      </p>
<p>
        It is a pretty common pattern to create a rule in order to get a certain
        kind of value out of a parser, when you don't normally get it automatically.
        If I want to parse an <code class="computeroutput"><span class="keyword">int</span></code>,
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aebfca0484fcebac2789c946c6a93b116.html" title="Global int_">int_</a></code>
        does that, and the thing that I parsed is also the desired attribute. If
        I parse an <code class="computeroutput"><span class="keyword">int</span></code> followed by a
        <code class="computeroutput"><span class="keyword">double</span></code>, I get a <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a8a805831f8b910ea5e79472b7af8b016.html" title="Type definition tuple">boost::parser::tuple</a></code> containing one of each.
        But what if I don't want those two values, but some function of those two
        values? I probably write something like this.
      </p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">obj_t</span> <span class="special">{</span> <span class="comment">/* ... */</span> <span class="special">};</span>
<span class="identifier">obj_t</span> <span class="identifier">to_obj</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">{</span> <span class="comment">/* ... */</span> <span class="special">}</span>

<span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">obj_tag</span><span class="special">,</span> <span class="identifier">obj_t</span><span class="special">&gt;</span> <span class="identifier">obj</span> <span class="special">=</span> <span class="string">"obj"</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">make_obj</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span>
    <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
    <span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">to_obj</span><span class="special">(</span><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)[</span><span class="number">0</span><span class="identifier">_c</span><span class="special">],</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)[</span><span class="number">1</span><span class="identifier">_c</span><span class="special">]);</span>
<span class="special">};</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">obj_def</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span><span class="special">)[</span><span class="identifier">make_obj</span><span class="special">];</span>
</pre>
<p>
        That's fine, if a little verbose. However, you can also do this instead:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">obj_tag</span><span class="special">,</span> <span class="identifier">obj_t</span><span class="special">&gt;</span> <span class="identifier">obj</span> <span class="special">=</span> <span class="string">"obj"</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">make_obj</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="special">{</span>
    <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
    <span class="keyword">return</span> <span class="identifier">to_obj</span><span class="special">(</span><span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)[</span><span class="number">0</span><span class="identifier">_c</span><span class="special">],</span> <span class="identifier">_attr</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)[</span><span class="number">1</span><span class="identifier">_c</span><span class="special">]);</span>
<span class="special">};</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">obj_def</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span><span class="special">)[</span><span class="identifier">make_obj</span><span class="special">];</span>
</pre>
<p>
        Above, we return the value from a semantic action, and the returned value
        gets assigned to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3786fbbcb7262b8da0b87e7ac30e37.html" title="Function _val">_val</a><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>.
      </p>
<p>
        Finally, you can provide a function that takes the individual elements of
        the attribute (if it's a tuple), and returns the value to assign to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1abb3786fbbcb7262b8da0b87e7ac30e37.html" title="Function _val">_val</a><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="identifier">bp</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">obj_tag</span><span class="special">,</span> <span class="identifier">obj_t</span><span class="special">&gt;</span> <span class="identifier">obj</span> <span class="special">=</span> <span class="string">"obj"</span><span class="special">;</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">obj_def</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">double_</span><span class="special">)[</span><span class="identifier">to_obj</span><span class="special">];</span>
</pre>
<p>
        More formally, within a rule, the use of a semantic action is determined
        as follows. Assume we have a function <code class="computeroutput"><span class="identifier">APPLY</span></code>
        that calls a function with the elements of a tuple, like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">apply</span></code>.
        For some context <code class="computeroutput"><span class="identifier">ctx</span></code>, semantic
        action <code class="computeroutput"><span class="identifier">action</span></code>, and attribute
        <code class="computeroutput"><span class="identifier">attr</span></code>, <code class="computeroutput"><span class="identifier">action</span></code>
        is used like this:
      </p>
<p>
        - <code class="computeroutput"><span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">=</span>
        <span class="identifier">APPLY</span><span class="special">(</span><span class="identifier">action</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">attr</span><span class="special">))</span></code>,
        if that is well-formed, and <code class="computeroutput"><span class="identifier">attr</span></code>
        is a tuple of size 2 or larger;
      </p>
<p>
        - otherwise, <code class="computeroutput"><span class="identifier">_val</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span> <span class="special">=</span>
        <span class="identifier">action</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>, if
        that is well-formed;
      </p>
<p>
        - otherwise, <code class="computeroutput"><span class="identifier">action</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>.
      </p>
<p>
        The first case does not pass the context to the action at all. The last case
        is the normal use of semantic actions outside of rules.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.algorithms_and_views_that_use_parsers"></a><a class="link" href="tutorial.html#boost_parser.tutorial.algorithms_and_views_that_use_parsers" title="Algorithms and Views That Use Parsers">Algorithms
      and Views That Use Parsers</a>
</h3></div></div></div>
<p>
        Unless otherwise noted, all the algorithms and views are constrained very
        much like the way the <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        overloads are. The kinds of ranges, parsers, etc., that they accept are the
        same.
      </p>
<h5>
<a name="boost_parser.tutorial.algorithms_and_views_that_use_parsers.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.algorithms_and_views_that_use_parsers._functionname_alt__boost__parser__search___code__phrase_role__identifier__boost__phrase__phrase_role__special______phrase__phrase_role__identifier__parser__phrase__phrase_role__special______phrase__phrase_role__identifier__search__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.algorithms_and_views_that_use_parsers._functionname_alt__boost__parser__search___code__phrase_role__identifier__boost__phrase__phrase_role__special______phrase__phrase_role__identifier__parser__phrase__phrase_role__special______phrase__phrase_role__identifier__search__phrase__phrase_role__special______phrase___code___functionname_">boost::parser::search()</a>
      </h5>
<p>
        As shown in <a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api" title="The parse() API">The
        <code class="computeroutput"><span class="identifier">parse</span><span class="special">()</span></code>
        API</a>, the two patterns of parsing in Boost.Parser are whole-parse and
        prefix-parse. When you want to find something in the middle of the range
        being parsed, there's no <code class="computeroutput"><span class="identifier">parse</span></code>
        API for that. You can of course make a simple parser that skips everything
        before what you're looking for.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="comment">/* ... */</span><span class="special">;</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">middle_parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">omit</span><span class="special">[*(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">-</span> <span class="identifier">parser</span><span class="special">)]</span> <span class="special">&gt;&gt;</span> <span class="identifier">parser</span><span class="special">;</span>
</pre>
<p>
        <code class="computeroutput"><span class="identifier">middle_parser</span></code> will skip over
        everything, one <code class="computeroutput"><span class="identifier">char_</span></code> at
        a time, as long as the next <code class="computeroutput"><span class="identifier">char_</span></code>
        is not the beginning of a successful match of <code class="computeroutput"><span class="identifier">parser</span></code>.
        After this, control passes to <code class="computeroutput"><span class="identifier">parser</span></code>
        itself. Ok, so that's not too hard to write. If you need to parse something
        from the middle in order to generate attributes, this is what you should
        use.
      </p>
<p>
        However, it often turns out you only need to find some subrange in the parsed
        range. In these cases, it would be nice to turn this into a proper algorithm
        in the pattern of the ones in <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ranges</span></code>,
        since that's more idiomatic. <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7bbfe78dff6388c09bd09253f3cf86ba.html" title="Function template search">boost::parser::search()</a></code>
        is that algorithm. It has very similar semantics to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ranges</span><span class="special">::</span><span class="identifier">search</span></code>,
        except that it searches not for a match to an exact subrange, but to a match
        with the given parser. Like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ranges</span><span class="special">::</span><span class="identifier">search</span><span class="special">()</span></code>, it returns a subrange (<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">subrange</span></code>
        in C++17, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ranges</span><span class="special">::</span><span class="identifier">subrange</span></code> in C++20 and later).
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">search</span><span class="special">(</span><span class="string">"aaXYZq"</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="string">"XYZ"</span><span class="special">),</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(!</span><span class="identifier">result</span><span class="special">.</span><span class="identifier">empty</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span><span class="special">(</span><span class="identifier">result</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> <span class="special">-</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">begin</span><span class="special">())</span> <span class="special">==</span> <span class="string">"XYZ"</span><span class="special">);</span>
</pre>
<p>
        Since <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7bbfe78dff6388c09bd09253f3cf86ba.html" title="Function template search">boost::parser::search()</a></code> returns a subrange, whatever
        parser you give it produces no attribute. I wrote <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="string">"XYZ"</span><span class="special">)</span></code>
        above; if I had written <code class="computeroutput"><span class="identifier">bp</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="string">"XYZ"</span><span class="special">)</span></code> instead, the result (and lack of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
        construction) would not change.
      </p>
<p>
        As you can see above, one aspect of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7bbfe78dff6388c09bd09253f3cf86ba.html" title="Function template search">boost::parser::search()</a></code>
        differs intentionally from the conventions of the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ranges</span></code>
        algorithms — it accepts C-style strings, treating them as if they
        were proper ranges.
      </p>
<p>
        Also, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7bbfe78dff6388c09bd09253f3cf86ba.html" title="Function template search">boost::parser::search()</a></code> knows how to accommodate
        your iterator type. You can pass the C-style string <code class="computeroutput"><span class="string">"aaXYZq"</span></code>
        as in the example above, or <code class="computeroutput"><span class="string">"aaXYZq"</span>
        <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf32</span></code>,
        or <code class="computeroutput"><span class="string">"aaXYZq"</span> <span class="special">|</span>
        <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf8</span></code>, or even <code class="computeroutput"><span class="string">"aaXYZq"</span>
        <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf16</span></code>,
        and it will return a subrange whose iterators are the type that you passed
        as input, even though internally the iterator type might be something different
        (a UTF-8 -&gt; UTF-32 transcoding iterator in Unicode parsing, as with all
        the <code class="computeroutput"><span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utfN</span></code>
        examples above). As long as you pass a range to be parsed whose value type
        is <code class="computeroutput"><span class="keyword">char</span></code>, <code class="computeroutput"><span class="identifier">char8_t</span></code>,
        <code class="computeroutput"><span class="keyword">char32_t</span></code>, or that is adapted
        using some combination of <code class="computeroutput"><span class="identifier">as_utfN</span></code>
        adaptors, this accommodation will operate correctly.
      </p>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7bbfe78dff6388c09bd09253f3cf86ba.html" title="Function template search">boost::parser::search()</a></code> has multiple overloads.
        You can pass a range or an iterator/sentinel pair, and you can pass a skip
        parser or not. That's four overloads. Also, all four overloads take an optional
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a70159b38d52d5203b78c0078c2f4e7f6.html" title="Type trace">boost::parser::trace</a></code>
        parameter at the end. This is really handy for investigating why you're not
        finding something in the input that you expected to.
      </p>
<h5>
<a name="boost_parser.tutorial.algorithms_and_views_that_use_parsers.h1"></a>
        <span class="phrase"><a name="boost_parser.tutorial.algorithms_and_views_that_use_parsers._globalname_alt__boost__parser__search_all___code__phrase_role__identifier__boost__phrase__phrase_role__special______phrase__phrase_role__identifier__parser__phrase__phrase_role__special______phrase__phrase_role__identifier__search_all__phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.algorithms_and_views_that_use_parsers._globalname_alt__boost__parser__search_all___code__phrase_role__identifier__boost__phrase__phrase_role__special______phrase__phrase_role__identifier__parser__phrase__phrase_role__special______phrase__phrase_role__identifier__search_all__phrase___code___globalname_">boost::parser::search_all</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aac706fbd46ce06e32693cd6b2a1b42cf.html" title="Global search_all">boost::parser::search_all</a></code>
        creates <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1search__all__view.html" title="Struct template search_all_view">boost::parser::search_all_views</a></code>.
        <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1search__all__view.html" title="Struct template search_all_view">boost::parser::search_all_view</a></code>
        is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">views</span></code>-style view. It produces a range of
        subranges. Each subrange it produces is the next match of the given parser
        in the parsed range.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">r</span> <span class="special">=</span> <span class="string">"XYZaaXYZbaabaXYZXYZ"</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">search_all</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="string">"XYZ"</span><span class="special">));</span>
<span class="keyword">int</span> <span class="identifier">count</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="comment">// Prints XYZ XYZ XYZ XYZ.</span>
<span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span> <span class="identifier">subrange</span> <span class="special">:</span> <span class="identifier">r</span><span class="special">)</span> <span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span><span class="special">(</span><span class="identifier">subrange</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">subrange</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> <span class="special">-</span> <span class="identifier">subrange</span><span class="special">.</span><span class="identifier">begin</span><span class="special">())</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span><span class="special">;</span>
    <span class="special">++</span><span class="identifier">count</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">count</span> <span class="special">==</span> <span class="number">4</span><span class="special">);</span>
</pre>
<p>
        All the details called out in the subsection on <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7bbfe78dff6388c09bd09253f3cf86ba.html" title="Function template search">boost::parser::search()</a></code>
        above apply to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aac706fbd46ce06e32693cd6b2a1b42cf.html" title="Global search_all">boost::parser::search_all</a></code>: its parser produces
        no attributes; it accepts C-style strings as if they were ranges; and it
        knows how to get from the internally-used iterator type back to the given
        iterator type, in typical cases.
      </p>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aac706fbd46ce06e32693cd6b2a1b42cf.html" title="Global search_all">boost::parser::search_all</a></code>
        can be called with, and <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1search__all__view.html" title="Struct template search_all_view">boost::parser::search_all_view</a></code> can be constructed
        with, a skip parser or not, and you can always pass <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a70159b38d52d5203b78c0078c2f4e7f6.html" title="Type trace">boost::parser::trace</a></code> at the end of any of their
        overloads.
      </p>
<h5>
<a name="boost_parser.tutorial.algorithms_and_views_that_use_parsers.h2"></a>
        <span class="phrase"><a name="boost_parser.tutorial.algorithms_and_views_that_use_parsers._globalname_alt__boost__parser__split___code__phrase_role__identifier__boost__phrase__phrase_role__special______phrase__phrase_role__identifier__parser__phrase__phrase_role__special______phrase__phrase_role__identifier__split__phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.algorithms_and_views_that_use_parsers._globalname_alt__boost__parser__split___code__phrase_role__identifier__boost__phrase__phrase_role__special______phrase__phrase_role__identifier__parser__phrase__phrase_role__special______phrase__phrase_role__identifier__split__phrase___code___globalname_">boost::parser::split</a>
      </h5>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a97519dee29e99043937f35176b4333f6.html" title="Global split">boost::parser::split</a></code>
        creates <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1split__view.html" title="Struct template split_view">boost::parser::split_views</a></code>.
        <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1split__view.html" title="Struct template split_view">boost::parser::split_view</a></code>
        is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">views</span></code>-style view. It produces a range of
        subranges of the parsed range split on matches of the given parser. You can
        think of <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1split__view.html" title="Struct template split_view">boost::parser::split_view</a></code>
        as being the complement of <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1search__all__view.html" title="Struct template search_all_view">boost::parser::search_all_view</a></code>, in that <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1split__view.html" title="Struct template split_view">boost::parser::split_view</a></code>
        produces the subranges between the subranges produced by <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1search__all__view.html" title="Struct template search_all_view">boost::parser::search_all_view</a></code>. <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1split__view.html" title="Struct template split_view">boost::parser::split_view</a></code>
        has very similar semantics to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">views</span><span class="special">::</span><span class="identifier">split_view</span></code>.
        Just like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">views</span><span class="special">::</span><span class="identifier">split_view</span></code>, <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1split__view.html" title="Struct template split_view">boost::parser::split_view</a></code> will produce empty
        ranges between the beginning/end of the parsed range and an adjacent match,
        or between adjacent matches.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">r</span> <span class="special">=</span> <span class="string">"XYZaaXYZbaabaXYZXYZ"</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">split</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="string">"XYZ"</span><span class="special">));</span>
<span class="keyword">int</span> <span class="identifier">count</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="comment">// Prints '' 'aa' 'baaba' '' ''.</span>
<span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span> <span class="identifier">subrange</span> <span class="special">:</span> <span class="identifier">r</span><span class="special">)</span> <span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"'"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span><span class="special">(</span><span class="identifier">subrange</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">subrange</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> <span class="special">-</span> <span class="identifier">subrange</span><span class="special">.</span><span class="identifier">begin</span><span class="special">())</span> <span class="special">&lt;&lt;</span> <span class="string">"' "</span><span class="special">;</span>
    <span class="special">++</span><span class="identifier">count</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">count</span> <span class="special">==</span> <span class="number">5</span><span class="special">);</span>
</pre>
<p>
        All the details called out in the subsection on <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7bbfe78dff6388c09bd09253f3cf86ba.html" title="Function template search">boost::parser::search()</a></code>
        above apply to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a97519dee29e99043937f35176b4333f6.html" title="Global split">boost::parser::split</a></code>:
        its parser produces no attributes; it accepts C-style strings as if they
        were ranges; and it knows how to get from the internally-used iterator type
        back to the given iterator type, in typical cases.
      </p>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a97519dee29e99043937f35176b4333f6.html" title="Global split">boost::parser::split</a></code>
        can be called with, and <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1split__view.html" title="Struct template split_view">boost::parser::split_view</a></code> can be constructed
        with, a skip parser or not, and you can always pass <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a70159b38d52d5203b78c0078c2f4e7f6.html" title="Type trace">boost::parser::trace</a></code> at the end of any of their
        overloads.
      </p>
<h5>
<a name="boost_parser.tutorial.algorithms_and_views_that_use_parsers.h3"></a>
        <span class="phrase"><a name="boost_parser.tutorial.algorithms_and_views_that_use_parsers._globalname_alt__boost__parser__replace___code__phrase_role__identifier__boost__phrase__phrase_role__special______phrase__phrase_role__identifier__parser__phrase__phrase_role__special______phrase__phrase_role__identifier__replace__phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.algorithms_and_views_that_use_parsers._globalname_alt__boost__parser__replace___code__phrase_role__identifier__boost__phrase__phrase_role__special______phrase__phrase_role__identifier__parser__phrase__phrase_role__special______phrase__phrase_role__identifier__replace__phrase___code___globalname_">boost::parser::replace</a>
      </h5>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2e04f251ac1f69e050ec228d4892b8a6.html" title="Global replace">boost::parser::replace</a></code>
          and <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1replace__view.html" title="Struct template replace_view">boost::parser::replace_view</a></code>
          are not available on MSVC in C++17 mode.
        </p></td></tr>
</table></div>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2e04f251ac1f69e050ec228d4892b8a6.html" title="Global replace">boost::parser::replace</a></code>
        creates <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1replace__view.html" title="Struct template replace_view">boost::parser::replace_views</a></code>.
        <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1replace__view.html" title="Struct template replace_view">boost::parser::replace_view</a></code>
        is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">views</span></code>-style view. It produces a range of
        subranges from the parsed range <code class="computeroutput"><span class="identifier">r</span></code>
        and the given replacement range <code class="computeroutput"><span class="identifier">replacement</span></code>.
        Wherever in the parsed range a match to the given parser <code class="computeroutput"><span class="identifier">parser</span></code>
        is found, <code class="computeroutput"><span class="identifier">replacement</span></code> is
        the subrange produced. Each subrange of <code class="computeroutput"><span class="identifier">r</span></code>
        that does not match <code class="computeroutput"><span class="identifier">parser</span></code>
        is produced as a subrange as well. The subranges are produced in the order
        in which they occur in <code class="computeroutput"><span class="identifier">r</span></code>.
        Unlike <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1split__view.html" title="Struct template split_view">boost::parser::split_view</a></code>,
        <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1replace__view.html" title="Struct template replace_view">boost::parser::replace_view</a></code>
        does not produce empty subranges, unless <code class="computeroutput"><span class="identifier">replacement</span></code>
        is empty.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">card_number</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">repeat</span><span class="special">(</span><span class="number">3</span><span class="special">)[</span><span class="char">'-'</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">];</span>
<span class="keyword">auto</span> <span class="identifier">rng</span> <span class="special">=</span> <span class="string">"My credit card number is 1234-5678-9012-3456."</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">replace</span><span class="special">(</span><span class="identifier">card_number</span><span class="special">,</span> <span class="string">"XXXX-XXXX-XXXX-XXXX"</span><span class="special">);</span>
<span class="keyword">int</span> <span class="identifier">count</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="comment">// Prints My credit card number is XXXX-XXXX-XXXX-XXXX.</span>
<span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span> <span class="identifier">subrange</span> <span class="special">:</span> <span class="identifier">rng</span><span class="special">)</span> <span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span><span class="special">(</span><span class="identifier">subrange</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">subrange</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> <span class="special">-</span> <span class="identifier">subrange</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span>
    <span class="special">++</span><span class="identifier">count</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">count</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
</pre>
<p>
        If the iterator types <code class="computeroutput"><span class="identifier">Ir</span></code>
        and <code class="computeroutput"><span class="identifier">Ireplacement</span></code> for the
        <code class="computeroutput"><span class="identifier">r</span></code> and <code class="computeroutput"><span class="identifier">replacement</span></code>
        ranges passed are identical (as in the example above), the iterator type
        for the subranges produced is <code class="computeroutput"><span class="identifier">Ir</span></code>.
        If they are different, an implementation-defined type is used for the iterator.
        This type is the moral equivalent of a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">Ir</span><span class="special">,</span> <span class="identifier">Ireplacement</span><span class="special">&gt;</span></code>. This works as long as <code class="computeroutput"><span class="identifier">Ir</span></code> and <code class="computeroutput"><span class="identifier">Ireplacement</span></code>
        are compatible. To be compatible, they must have common reference, value,
        and rvalue reference types, as determined by <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type_t</span></code>.
        One advantage to this scheme is that the range of subranges represented by
        <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1replace__view.html" title="Struct template replace_view">boost::parser::replace_view</a></code>
        is easily joined back into a single range.
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">card_number</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">repeat</span><span class="special">(</span><span class="number">3</span><span class="special">)[</span><span class="char">'-'</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">];</span>
<span class="keyword">auto</span> <span class="identifier">rng</span> <span class="special">=</span> <span class="string">"My credit card number is 1234-5678-9012-3456."</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">replace</span><span class="special">(</span><span class="identifier">card_number</span><span class="special">,</span> <span class="string">"XXXX-XXXX-XXXX-XXXX"</span><span class="special">)</span> <span class="special">|</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">views</span><span class="special">::</span><span class="identifier">join</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">replace_result</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span> <span class="identifier">ch</span> <span class="special">:</span> <span class="identifier">rng</span><span class="special">)</span> <span class="special">{</span>
    <span class="identifier">replace_result</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">ch</span><span class="special">);</span>
<span class="special">}</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">replace_result</span> <span class="special">==</span> <span class="string">"My credit card number is XXXX-XXXX-XXXX-XXXX."</span><span class="special">);</span>
</pre>
<p>
        Note that we could <span class="bold"><strong>not</strong></span> have written <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span>
        <span class="identifier">replace_result</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">end</span><span class="special">())</span></code>.
        This is ill-formed because the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
        range constructor takes two iterators of the same type, but <code class="computeroutput"><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">rng</span><span class="special">.</span><span class="identifier">end</span><span class="special">())</span></code> is a sentinel type different from <code class="computeroutput"><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">rng</span><span class="special">.</span><span class="identifier">begin</span><span class="special">())</span></code>.
      </p>
<p>
        Though the ranges <code class="computeroutput"><span class="identifier">r</span></code> and
        <code class="computeroutput"><span class="identifier">replacement</span></code> can both be C-style
        strings, <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1replace__view.html" title="Struct template replace_view">boost::parser::replace_view</a></code>
        must know the end of <code class="computeroutput"><span class="identifier">replacement</span></code>
        before it does any work. This is because the subranges produced are all common
        ranges, and so if <code class="computeroutput"><span class="identifier">replacement</span></code>
        is not, a common range must be formed from it. If you expect to pass very
        long C-style strings to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2e04f251ac1f69e050ec228d4892b8a6.html" title="Global replace">boost::parser::replace</a></code> and not pay to see
        the end until the range is used, don't.
      </p>
<p>
        <code class="computeroutput"><span class="identifier">ReplacementV</span></code> is constrained
        almost exactly the same as <code class="computeroutput"><span class="identifier">V</span></code>.
        <code class="computeroutput"><span class="identifier">V</span></code> must model <code class="computeroutput"><span class="identifier">parsable_range</span></code> and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ranges</span><span class="special">::</span><span class="identifier">viewable_range</span></code>.
        <code class="computeroutput"><span class="identifier">ReplacementV</span></code> is the same,
        except that it can also be a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ranges</span><span class="special">::</span><span class="identifier">input_range</span></code>,
        whereas <code class="computeroutput"><span class="identifier">V</span></code> must be a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ranges</span><span class="special">::</span><span class="identifier">forward_range</span></code>.
      </p>
<p>
        You may wonder what happens when you pass a UTF-N range for <code class="computeroutput"><span class="identifier">r</span></code>, and a UTF-M range for <code class="computeroutput"><span class="identifier">replacement</span></code>. What happens in this case
        is silent transcoding of <code class="computeroutput"><span class="identifier">replacement</span></code>
        from UTF-M to UTF-N by the <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2e04f251ac1f69e050ec228d4892b8a6.html" title="Global replace">boost::parser::replace</a></code> range adaptor. This
        doesn't require memory allocation; <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2e04f251ac1f69e050ec228d4892b8a6.html" title="Global replace">boost::parser::replace</a></code> just slaps <code class="computeroutput"><span class="special">|</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">as_utfN</span></code>
        onto <code class="computeroutput"><span class="identifier">replacement</span></code>. However,
        since Boost.Parser treats <code class="computeroutput"><span class="keyword">char</span></code>
        ranges as unknown encoding, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2e04f251ac1f69e050ec228d4892b8a6.html" title="Global replace">boost::parser::replace</a></code> will not transcode
        from <code class="computeroutput"><span class="keyword">char</span></code> ranges. So calls like
        this won't work:
      </p>
<pre class="programlisting"><span class="keyword">char</span> <span class="keyword">const</span> <span class="identifier">str</span><span class="special">[]</span> <span class="special">=</span> <span class="string">"some text"</span><span class="special">;</span>
<span class="keyword">char</span> <span class="keyword">const</span> <span class="identifier">replacement_str</span><span class="special">[]</span> <span class="special">=</span> <span class="string">"some text"</span><span class="special">;</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">r</span> <span class="special">=</span> <span class="identifier">empty_str</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">replace</span><span class="special">(</span><span class="identifier">parser</span><span class="special">,</span> <span class="identifier">replacement_str</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf8</span><span class="special">);</span> <span class="comment">// Error: ill-formed!  Can't mix plain-char inputs and UTF replacements.</span>
</pre>
<p>
        This does not work, even though <code class="computeroutput"><span class="keyword">char</span></code>
        and UTF-8 are the same size. If <code class="computeroutput"><span class="identifier">r</span></code>
        and <code class="computeroutput"><span class="identifier">replacement</span></code> are both
        ranges of <code class="computeroutput"><span class="keyword">char</span></code>, everything will
        work of course. It's just mixing <code class="computeroutput"><span class="keyword">char</span></code>
        and UTF-encoded ranges that does not work.
      </p>
<p>
        All the details called out in the subsection on <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7bbfe78dff6388c09bd09253f3cf86ba.html" title="Function template search">boost::parser::search()</a></code>
        above apply to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2e04f251ac1f69e050ec228d4892b8a6.html" title="Global replace">boost::parser::replace</a></code>:
        its parser produces no attributes; it accepts C-style strings for the <code class="computeroutput"><span class="identifier">r</span></code> and <code class="computeroutput"><span class="identifier">replacement</span></code>
        parameters as if they were ranges; and it knows how to get from the internally-used
        iterator type back to the given iterator type, in typical cases.
      </p>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2e04f251ac1f69e050ec228d4892b8a6.html" title="Global replace">boost::parser::replace</a></code>
        can be called with, and <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1replace__view.html" title="Struct template replace_view">boost::parser::replace_view</a></code> can be constructed
        with, a skip parser or not, and you can always pass <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a70159b38d52d5203b78c0078c2f4e7f6.html" title="Type trace">boost::parser::trace</a></code> at the end of any of their
        overloads.
      </p>
<h5>
<a name="boost_parser.tutorial.algorithms_and_views_that_use_parsers.h4"></a>
        <span class="phrase"><a name="boost_parser.tutorial.algorithms_and_views_that_use_parsers._globalname_alt__boost__parser__transform_replace___code__phrase_role__identifier__boost__phrase__phrase_role__special______phrase__phrase_role__identifier__parser__phrase__phrase_role__special______phrase__phrase_role__identifier__transform_replace__phrase___code___globalname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.algorithms_and_views_that_use_parsers._globalname_alt__boost__parser__transform_replace___code__phrase_role__identifier__boost__phrase__phrase_role__special______phrase__phrase_role__identifier__parser__phrase__phrase_role__special______phrase__phrase_role__identifier__transform_replace__phrase___code___globalname_">boost::parser::transform_replace</a>
      </h5>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a129011968488bfeed50df4a6a31b0324.html" title="Global transform_replace">boost::parser::transform_replace</a></code>
          and <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1transform__replace__view.html" title="Struct template transform_replace_view">boost::parser::transform_replace_view</a></code> are
          not available on MSVC in C++17 mode.
        </p></td></tr>
</table></div>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a129011968488bfeed50df4a6a31b0324.html" title="Global transform_replace">boost::parser::transform_replace</a></code>
          and <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1transform__replace__view.html" title="Struct template transform_replace_view">boost::parser::transform_replace_view</a></code> are
          not available on GCC in C++20 mode before GCC 12.
        </p></td></tr>
</table></div>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a129011968488bfeed50df4a6a31b0324.html" title="Global transform_replace">boost::parser::transform_replace</a></code>
        creates <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1transform__replace__view.html" title="Struct template transform_replace_view">boost::parser::transform_replace_views</a></code>. <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1transform__replace__view.html" title="Struct template transform_replace_view">boost::parser::transform_replace_view</a></code>
        is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">views</span></code>-style view. It produces a range of
        subranges from the parsed range <code class="computeroutput"><span class="identifier">r</span></code>
        and the given invocable <code class="computeroutput"><span class="identifier">f</span></code>.
        Wherever in the parsed range a match to the given parser <code class="computeroutput"><span class="identifier">parser</span></code>
        is found, let <code class="computeroutput"><span class="identifier">parser</span></code>'s attribute
        be <code class="computeroutput"><span class="identifier">attr</span></code>; <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">attr</span><span class="special">))</span></code> is the subrange produced. Each subrange
        of <code class="computeroutput"><span class="identifier">r</span></code> that does not match
        <code class="computeroutput"><span class="identifier">parser</span></code> is produced as a subrange
        as well. The subranges are produced in the order in which they occur in
        <code class="computeroutput"><span class="identifier">r</span></code>. Unlike <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1split__view.html" title="Struct template split_view">boost::parser::split_view</a></code>, <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1transform__replace__view.html" title="Struct template transform_replace_view">boost::parser::transform_replace_view</a></code> does
        not produce empty subranges, unless <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">attr</span><span class="special">))</span></code> is empty. Here is an example.
      </p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">string_sum</span> <span class="special">=</span> <span class="special">[](</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">ints</span><span class="special">)</span> <span class="special">{</span>
    <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">to_string</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">accumulate</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ints</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="number">0</span><span class="special">));</span>
<span class="special">};</span>

<span class="keyword">auto</span> <span class="identifier">rng</span> <span class="special">=</span> <span class="string">"There are groups of [1, 2, 3, 4, 5] in the set."</span> <span class="special">|</span>
           <span class="identifier">bp</span><span class="special">::</span><span class="identifier">transform_replace</span><span class="special">(</span><span class="char">'['</span> <span class="special">&gt;&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">%</span> <span class="char">','</span> <span class="special">&gt;&gt;</span> <span class="char">']'</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">ws</span><span class="special">,</span> <span class="identifier">string_sum</span><span class="special">);</span>
<span class="keyword">int</span> <span class="identifier">count</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="comment">// Prints "There are groups of 15 in the set".</span>
<span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span> <span class="identifier">subrange</span> <span class="special">:</span> <span class="identifier">rng</span><span class="special">)</span> <span class="special">{</span>
    <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span> <span class="identifier">ch</span> <span class="special">:</span> <span class="identifier">subrange</span><span class="special">)</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">ch</span><span class="special">;</span>
    <span class="special">}</span>
    <span class="special">++</span><span class="identifier">count</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">count</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
</pre>
<p>
        Let the type <code class="computeroutput"><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">f</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">attr</span><span class="special">)))</span></code>
        be <code class="computeroutput"><span class="identifier">Replacement</span></code>. <code class="computeroutput"><span class="identifier">Replacement</span></code> must be a range, and must be
        compatible with <code class="computeroutput"><span class="identifier">r</span></code>. See the
        description of <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1replace__view.html" title="Struct template replace_view">boost::parser::replace_view</a></code>'s iterator compatibility
        requirements in the section above for details.
      </p>
<p>
        As with <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2e04f251ac1f69e050ec228d4892b8a6.html" title="Global replace">boost::parser::replace</a></code>,
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a129011968488bfeed50df4a6a31b0324.html" title="Global transform_replace">boost::parser::transform_replace</a></code>
        can be flattened from a view of subranges into a view of elements by piping
        it to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">views</span><span class="special">::</span><span class="identifier">join</span></code>. See the section on <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2e04f251ac1f69e050ec228d4892b8a6.html" title="Global replace">boost::parser::replace</a></code> above for an example.
      </p>
<p>
        Just like <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a2e04f251ac1f69e050ec228d4892b8a6.html" title="Global replace">boost::parser::replace</a></code>
        and <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1replace__view.html" title="Struct template replace_view">boost::parser::replace_view</a></code>,
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a129011968488bfeed50df4a6a31b0324.html" title="Global transform_replace">boost::parser::transform_replace</a></code>
        and <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1transform__replace__view.html" title="Struct template transform_replace_view">boost::parser::transform_replace_view</a></code> do silent
        transcoding of the result to the appropriate UTF, if applicable. If both
        <code class="computeroutput"><span class="identifier">r</span></code> and <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">attr</span><span class="special">))</span></code> are ranges of <code class="computeroutput"><span class="keyword">char</span></code>,
        or are both the same UTF, no transcoding occurs. If one of <code class="computeroutput"><span class="identifier">r</span></code> and <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">attr</span><span class="special">))</span></code> is a range of <code class="computeroutput"><span class="keyword">char</span></code>
        and the other is some UTF, the program is ill-formed.
      </p>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1transform__replace__view.html" title="Struct template transform_replace_view">boost::parser::transform_replace_view</a></code>
        will move each attribute into <code class="computeroutput"><span class="identifier">f</span></code>;
        <code class="computeroutput"><span class="identifier">f</span></code> may move from the argument
        or copy it as desired. <code class="computeroutput"><span class="identifier">f</span></code>
        may return an lvalue reference. If it does so, the address of the reference
        will be taken and stored within <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1transform__replace__view.html" title="Struct template transform_replace_view">boost::parser::transform_replace_view</a></code>. Otherwise,
        the value returned by <code class="computeroutput"><span class="identifier">f</span></code> is
        moved into <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1transform__replace__view.html" title="Struct template transform_replace_view">boost::parser::transform_replace_view</a></code>. In
        either case, the value type of <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1transform__replace__view.html" title="Struct template transform_replace_view">boost::parser::transform_replace_view</a></code> is always
        a subrange.
      </p>
<p>
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a129011968488bfeed50df4a6a31b0324.html" title="Global transform_replace">boost::parser::transform_replace</a></code>
        can be called with, and <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1transform__replace__view.html" title="Struct template transform_replace_view">boost::parser::transform_replace_view</a></code> can
        be constructed with, a skip parser or not, and you can always pass <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a70159b38d52d5203b78c0078c2f4e7f6.html" title="Type trace">boost::parser::trace</a></code>
        at the end of any of their overloads.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.unicode_support"></a><a class="link" href="tutorial.html#boost_parser.tutorial.unicode_support" title="Unicode Support">Unicode Support</a>
</h3></div></div></div>
<p>
        Boost.Parser was designed from the start to be Unicode friendly. There are
        numerous references to the "Unicode code path" and the "non-Unicode
        code path" in the Boost.Parser documentation. Though there are in fact
        two code paths for Unicode and non-Unicode parsing, the code is not very
        different in the two code paths, as they are written generically. The only
        difference is that the Unicode code path parses the input as a range of code
        points, and the non-Unicode path does not. In effect, this means that, in
        the Unicode code path, when you call <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse</a><span class="special">(</span><span class="identifier">r</span><span class="special">,</span> <span class="identifier">p</span><span class="special">)</span></code> for some input range <code class="computeroutput"><span class="identifier">r</span></code>
        and some parser <code class="computeroutput"><span class="identifier">p</span></code>, the parse
        happens as if you called <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse</a><span class="special">(</span><span class="identifier">r</span> <span class="special">|</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">as_utf32</span><span class="special">,</span> <span class="identifier">p</span><span class="special">)</span></code>
        instead. (Of course, it does not matter if <code class="computeroutput"><span class="identifier">r</span></code>
        is a proper range, or an iterator/sentinel pair; those both work fine with
        <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">as_utf32</span></code>.)
      </p>
<p>
        Matching "characters" within Boost.Parser's parsers is assumed
        to be a code point match. In the Unicode path there is a code point from
        the input that is matched to each <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code> parser. In the non-Unicode
        path, the encoding is unknown, and so each element of the input is considered
        to be a whole "character" in the input encoding, analogous to a
        code point. From this point on, I will therefore refer to a single element
        of the input exclusively as a code point.
      </p>
<p>
        So, let's say we write this parser:
      </p>
<pre class="programlisting"><span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">char8_parser</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'\xcc'</span><span class="special">);</span>
</pre>
<p>
        For any <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>
        parser that should match a value or values, the type of the value to match
        is retained. So <code class="computeroutput"><span class="identifier">char8_parser</span></code>
        contains a <code class="computeroutput"><span class="keyword">char</span></code> that it will
        use for matching. If we had written:
      </p>
<pre class="programlisting"><span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">char32_parser</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="identifier">U</span><span class="char">'\xcc'</span><span class="special">);</span>
</pre>
<p>
        <code class="computeroutput"><span class="identifier">char32_parser</span></code> would instead
        contain a <code class="computeroutput"><span class="keyword">char32_t</span></code> that it would
        use for matching.
      </p>
<p>
        So, at any point during the parse, if <code class="computeroutput"><span class="identifier">char8_parser</span></code>
        were being used to match a code point <code class="computeroutput"><span class="identifier">next_cp</span></code>
        from the input, we would see the moral equivalent of <code class="computeroutput"><span class="identifier">next_cp</span>
        <span class="special">==</span> <span class="char">'\xcc'</span></code>,
        and if <code class="computeroutput"><span class="identifier">char32_parser</span></code> were
        being used to match <code class="computeroutput"><span class="identifier">next_cp</span></code>,
        we'd see the equivalent of <code class="computeroutput"><span class="identifier">next_cp</span>
        <span class="special">==</span> <span class="identifier">U</span><span class="char">'\xcc'</span></code>. The take-away here is that you can write
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>
        parsers that match specific values, without worrying if the input is Unicode
        or not because, under the covers, what takes place is a simple comparison
        of two integral values.
      </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          Boost.Parser actually promotes any two values to a common type using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type</span></code> before comparing them. This
          is almost always works because the input and any parameter passed to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>
          must be character types.
        </p></td></tr>
</table></div>
<p>
        Since matches are always done at a code point level (remember, a "code
        point" in the non-Unicode path is assumed to be a single <code class="computeroutput"><span class="keyword">char</span></code>), you get different results trying to
        match UTF-8 input in the Unicode and non-Unicode code paths:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">str</span> <span class="special">=</span> <span class="special">(</span><span class="keyword">char</span> <span class="keyword">const</span> <span class="special">*)</span><span class="identifier">u8</span><span class="string">"\xcc\x80"</span><span class="special">;</span> <span class="comment">// encodes the code point U+0300</span>
    <span class="keyword">auto</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span>

    <span class="comment">// Since we've done nothing to indicate that we want to do Unicode</span>
    <span class="comment">// parsing, and we've passed a range of char to parse(), this will do</span>
    <span class="comment">// non-Unicode parsing.</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">chars</span><span class="special">;</span>
    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'\xcc'</span><span class="special">),</span> <span class="identifier">chars</span><span class="special">));</span>

    <span class="comment">// Finds one match of the *char* 0xcc, because the value in the parser</span>
    <span class="comment">// (0xcc) was matched against the two code points in the input (0xcc and</span>
    <span class="comment">// 0x80), and the first one was a match.</span>
    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">chars</span> <span class="special">==</span> <span class="string">"\xcc"</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">u8string</span> <span class="identifier">str</span> <span class="special">=</span> <span class="identifier">u8</span><span class="string">"\xcc\x80"</span><span class="special">;</span> <span class="comment">// encodes the code point U+0300</span>
    <span class="keyword">auto</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span>

    <span class="comment">// Since the input is a range of char8_t, this will do Unicode</span>
    <span class="comment">// parsing.  The same thing would have happened if we passed</span>
    <span class="comment">// str | boost::parser::as_utf32 or even str | boost::parser::as_utf8.</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">chars</span><span class="special">;</span>
    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">str</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="special">*</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span><span class="special">(</span><span class="char">'\xcc'</span><span class="special">),</span> <span class="identifier">chars</span><span class="special">));</span>

    <span class="comment">// Finds zero matches of the *code point* 0xcc, because the value in</span>
    <span class="comment">// the parser (0xcc) was matched against the single code point in the</span>
    <span class="comment">// input, 0x0300.</span>
    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">chars</span> <span class="special">==</span> <span class="string">""</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<h5>
<a name="boost_parser.tutorial.unicode_support.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.unicode_support.implicit_transcoding"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.unicode_support.implicit_transcoding">Implicit
        transcoding</a>
      </h5>
<p>
        Additionally, it is expected that most programs will use UTF-8 for the encoding
        of Unicode strings. Boost.Parser is written with this typical case in mind.
        This means that if you are parsing 32-bit code points (as you always are
        in the Unicode path), and you want to catch the result in a container <code class="computeroutput"><span class="identifier">C</span></code> of <code class="computeroutput"><span class="keyword">char</span></code>
        or <code class="computeroutput"><span class="identifier">char8_t</span></code> values, Boost.Parser
        will silently transcode from UTF-32 to UTF-8 and write the attribute into
        <code class="computeroutput"><span class="identifier">C</span></code>. This means that <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>,
        <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">u8string</span></code>, etc. are fine to use as attribute
        out-parameters for <code class="computeroutput"><span class="special">*</span><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>, and the result
        will be UTF-8.
      </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
          UTF-16 strings as attributes are not supported directly. If you want to
          use UTF-16 strings as attributes, you may need to do so by transcoding
          a UTF-8 or UTF-32 attribute to UTF-16 within a semantic action. You can
          do this by using <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">as_utf16</span></code>.
        </p></td></tr>
</table></div>
<p>
        The treatment of strings as UTF-8 is nearly ubiquitous within Boost.Parser.
        For instance, though the entire interface of <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code> uses <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
        or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span></code>, UTF-32 comparisons are used
        internally.
      </p>
<h5>
<a name="boost_parser.tutorial.unicode_support.h1"></a>
        <span class="phrase"><a name="boost_parser.tutorial.unicode_support.explicit_transcoding"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.unicode_support.explicit_transcoding">Explicit
        transcoding</a>
      </h5>
<p>
        I mentioned above that the use of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">utf</span><span class="special">*</span><span class="identifier">_view</span></code> as the range to parse opts you in
        to Unicode parsing. Here's a bit more about these views and how best to use
        them.
      </p>
<p>
        If you want to do Unicode parsing, you're always going to be comparing code
        points at each step of the parse. As such, you're going to implicitly convert
        any parse input to UTF-32, if needed. This is what all the parse API functions
        do internally.
      </p>
<p>
        However, there are times when you have parse input that is a sequence of
        UTF-8-encoded <code class="computeroutput"><span class="keyword">char</span></code>s, and you
        want to do Unicode-aware parsing. As mentioned previously, Boost.Parser has
        a special case for <code class="computeroutput"><span class="keyword">char</span></code> inputs,
        and it will <span class="bold"><strong>not</strong></span> assume that <code class="computeroutput"><span class="keyword">char</span></code> sequences are UTF-8. If you want to tell
        the parse API to do Unicode processing on them anyway, you can use the <code class="computeroutput"><span class="identifier">as_utf32</span></code> range adapter. (Note that you
        can use any of the <code class="computeroutput"><span class="identifier">as_utf</span><span class="special">*</span></code> adaptors and the semantics will not differ
        from the semantics below.)
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">;</span>

<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">p</span> <span class="special">=</span> <span class="char">'"'</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="identifier">bp</span><span class="special">::</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'"'</span> <span class="special">-</span> <span class="number">0xb6</span><span class="special">)</span> <span class="special">&gt;&gt;</span> <span class="char">'"'</span><span class="special">;</span>
<span class="keyword">char</span> <span class="keyword">const</span> <span class="special">*</span> <span class="identifier">str</span> <span class="special">=</span> <span class="string">"\"two wörds\""</span><span class="special">;</span> <span class="comment">// ö is two code units, 0xc3 0xb6</span>

<span class="keyword">auto</span> <span class="identifier">result_1</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">p</span><span class="special">);</span>                <span class="comment">// Treat each char as a code point (typically ASCII).</span>
<span class="identifier">assert</span><span class="special">(!</span><span class="identifier">result_1</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">result_2</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">str</span> <span class="special">|</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">as_utf32</span><span class="special">,</span> <span class="identifier">p</span><span class="special">);</span> <span class="comment">// Unicode-aware parsing on code points.</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">result_2</span><span class="special">);</span>
</pre>
<p>
        The first call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        treats each <code class="computeroutput"><span class="keyword">char</span></code> as a code point,
        and since <code class="computeroutput"><span class="string">"ö"</span></code> is the
        pair of code units <code class="computeroutput"><span class="number">0xc3</span></code> <code class="computeroutput"><span class="number">0xb6</span></code>, the parse matches the second code unit
        against the <code class="computeroutput"><span class="special">-</span> <span class="number">0xb6</span></code>
        part of the parser above, causing the parse to fail. This happens because
        each code unit/<code class="computeroutput"><span class="keyword">char</span></code> in <code class="computeroutput"><span class="identifier">str</span></code> is treated as an independent code point.
      </p>
<p>
        The second call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        succeeds because, when the parse gets to the code point for <code class="computeroutput"><span class="char">'ö'</span></code>, it is <code class="computeroutput"><span class="number">0xf6</span></code>
        (U+00F6), which does not match the <code class="computeroutput"><span class="special">-</span>
        <span class="number">0xb6</span></code> part of the parser.
      </p>
<p>
        The other adaptors <code class="computeroutput"><span class="identifier">as_utf8</span></code>
        and <code class="computeroutput"><span class="identifier">as_utf16</span></code> are also provided
        for completeness, if you want to use them. They each can transcode any sequence
        of character types.
      </p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          The <code class="computeroutput"><span class="identifier">as_utfN</span></code> adaptors are
          optional, so they don't come with <code class="computeroutput"><span class="identifier">parser</span><span class="special">.</span><span class="identifier">hpp</span></code>.
          To get access to them, <code class="computeroutput"><span class="preprocessor">#include</span>
          <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">parser</span><span class="special">/</span><span class="identifier">transcode_view</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>.
        </p></td></tr>
</table></div>
<h5>
<a name="boost_parser.tutorial.unicode_support.h2"></a>
        <span class="phrase"><a name="boost_parser.tutorial.unicode_support._lack_of__normalization"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.unicode_support._lack_of__normalization">(Lack
        of) normalization</a>
      </h5>
<p>
        One thing that Boost.Parser does not handle for you is normalization; Boost.Parser
        is completely normalization-agnostic. Since all the parsers do their matching
        using equality comparisons of code points, you should make sure that your
        parsed range and your parsers all use the same normalization form.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.callback_parsing"></a><a class="link" href="tutorial.html#boost_parser.tutorial.callback_parsing" title="Callback Parsing">Callback Parsing</a>
</h3></div></div></div>
<p>
        In most parsing cases, being able to generate an attribute that represents
        the result of the parse, or being able to parse into such an attribute, is
        sufficient. Sometimes, it is not. If you need to parse a very large chunk
        of text, the generated attribute may be too large to fit in memory. In other
        cases, you may want to generate attributes sometimes, and not others. <code class="computeroutput">callback_rules</code>
        exist for these kinds of uses. A <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1callback__rule.html" title="Struct template callback_rule">callback_rule</a></code> is just like
        a rule, except that it allows the rule's attribute to be returned to the
        caller via a callback, as long as the parse is started with a call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab9e8e193ef875ca869f2d6d43fa61fc5.html" title="Function template callback_parse">callback_parse()</a></code> instead of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>. Within a call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>, a <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1callback__rule.html" title="Struct template callback_rule">callback_rule</a></code> is identical
        to a regular <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rule</a></code>.
      </p>
<p>
        For a rule with no attribute, the signature of a callback function is <code class="computeroutput"><span class="keyword">void</span> <span class="special">(</span><span class="identifier">tag</span><span class="special">)</span></code>, where <code class="computeroutput"><span class="identifier">tag</span></code>
        is the tag-type used when declaring the rule. For a rule with an attribute
        <code class="computeroutput"><span class="identifier">attr</span></code>, the signature is <code class="computeroutput"><span class="keyword">void</span> <span class="special">(</span><span class="identifier">tag</span><span class="special">,</span> <span class="identifier">attr</span><span class="special">)</span></code>. For instance, with this rule:
      </p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">callback_rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">foo_tag</span><span class="special">&gt;</span> <span class="identifier">foo</span> <span class="special">=</span> <span class="string">"foo"</span><span class="special">;</span>
</pre>
<p>
        this would be an appropriate callback function:
      </p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo_callback</span><span class="special">(</span><span class="identifier">foo_tag</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Parsed a 'foo'!\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
        For this rule:
      </p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">parser</span><span class="special">::</span><span class="identifier">callback_rule</span><span class="special">&lt;</span><span class="keyword">struct</span> <span class="identifier">bar_tag</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">bar</span> <span class="special">=</span> <span class="string">"bar"</span><span class="special">;</span>
</pre>
<p>
        this would be an appropriate callback function:
      </p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">bar_callback</span><span class="special">(</span><span class="identifier">bar_tag</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Parsed a 'bar' containing "</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="string">"!\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          In the case of <code class="computeroutput"><span class="identifier">bar_callback</span><span class="special">()</span></code>, we don't need to do anything with <code class="computeroutput"><span class="identifier">s</span></code> besides insert it into a stream, so
          we took it as a <code class="computeroutput"><span class="keyword">const</span></code> lvalue
          reference. Boost.Parser moves all attributes into callbacks, so the signature
          could also have been <code class="computeroutput"><span class="keyword">void</span> <span class="identifier">bar_callback</span><span class="special">(</span><span class="identifier">bar_tag</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">s</span><span class="special">)</span></code> or <code class="computeroutput"><span class="keyword">void</span>
          <span class="identifier">bar_callback</span><span class="special">(</span><span class="identifier">bar_tag</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;&amp;</span>
          <span class="identifier">s</span><span class="special">)</span></code>.
        </p></td></tr>
</table></div>
<p>
        You opt into callback parsing by parsing with a call to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab9e8e193ef875ca869f2d6d43fa61fc5.html" title="Function template callback_parse">callback_parse()</a></code>
        instead of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>. If you use <code class="computeroutput">callback_rules</code> with <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>, they're just regular <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>.
        This allows you to choose whether to do "normal" attribute-generating/attribute-assigning
        parsing with <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>, or callback parsing with
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab9e8e193ef875ca869f2d6d43fa61fc5.html" title="Function template callback_parse">callback_parse()</a></code>, without rewriting much
        parsing code, if any.
      </p>
<p>
        The only reason all <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code>
        are not <code class="computeroutput">callback_rules</code>
        is that you may want to have some <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rule.html" title="Struct template rule">rules</a></code> use callbacks within
        a parse, and have some that do not. For instance, if you want to report the
        attribute of <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1callback__rule.html" title="Struct template callback_rule">callback_rule</a></code> <code class="computeroutput"><span class="identifier">r1</span></code> via callback, <code class="computeroutput"><span class="identifier">r1</span></code>'s
        implementation may use some rule <code class="computeroutput"><span class="identifier">r2</span></code>
        to generate some or all of its attribute.
      </p>
<p>
        See <a class="link" href="extended_examples.html#boost_parser.extended_examples.parsing_json_with_callbacks" title="Parsing JSON With Callbacks">Parsing
        JSON With Callbacks</a> for an extended example of callback parsing.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.error_handling_and_debugging"></a><a class="link" href="tutorial.html#boost_parser.tutorial.error_handling_and_debugging" title="Error Handling and Debugging">Error
      Handling and Debugging</a>
</h3></div></div></div>
<h5>
<a name="boost_parser.tutorial.error_handling_and_debugging.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.error_handling_and_debugging.error_handling"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.error_handling_and_debugging.error_handling">Error
        handling</a>
      </h5>
<p>
        Boost.Parser has good error reporting built into it. Consider what happens
        when we fail to parse at an expectation point (created using <code class="computeroutput"><span class="keyword">operator</span><span class="special">&gt;</span></code>).
        If I feed the parser from the <a class="link" href="extended_examples.html#boost_parser.extended_examples.parsing_json_with_callbacks" title="Parsing JSON With Callbacks">Parsing
        JSON With Callbacks</a> example a file called sample.json containing this
        input (note the unmatched <code class="computeroutput"><span class="char">'['</span></code>):
      </p>
<p>
</p>
<pre class="programlisting">{
    "key": "value",
    "foo": [, "bar": []
}
</pre>
<p>
      </p>
<p>
        This is the error message that is printed to the terminal:
      </p>
<p>
</p>
<pre class="programlisting">sample.json:3:12: error: Expected ']' here:
    "foo": [, "bar": []
            ^
</pre>
<p>
      </p>
<p>
        That message is formatted like the diagnostics produced by Clang and GCC.
        It quotes the line on which the failure occurred, and even puts a caret under
        the exact position at which the parse failed. This error message is suitable
        for many kinds of end-users, and interoperates well with anything that supports
        Clang and/or GCC diagnostics.
      </p>
<p>
        Most of Boost.Parser's error handlers format their diagnostics this way,
        though you are not bound by that. You can make an error handler type that
        does whatever you want, as long as it meets the error handler interface.
      </p>
<p>
        The Boost.Parser error handlers are:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1default__error__handler.html" title="Struct default_error_handler">default_error_handler</a></code>:
            Produces formatted diagnostics like the one above, and prints them to
            <code class="computeroutput">std::cerr</code>. <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1default__error__handler.html" title="Struct default_error_handler">default_error_handler</a></code> has
            no associated file name, and both errors and diagnostics are printed
            to <code class="computeroutput">std::cerr</code>. This handler is <code class="computeroutput">constexpr</code>-friendly.
          </li>
<li class="listitem">
            <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1stream__error__handler.html" title="Struct stream_error_handler">stream_error_handler</a></code>:
            Produces formatted diagnostics. One or two streams may be used. If two
            are used, errors go to one stream and warnings go to the other. A file
            name can be associated with the parse; if it is, that file name will
            appear in all diagnostics.
          </li>
<li class="listitem">
            <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1callback__error__handler.html" title="Struct callback_error_handler">callback_error_handler</a></code>:
            Produces formatted diagnostics. Calls a callback with the diagnostic
            message to report the diagnostic, rather than streaming out the diagnostic.
            A file name can be associated with the parse; if it is, that file name
            will appear in all diagnostics. This handler is useful for recording
            the diagnostics in memory.
          </li>
<li class="listitem">
            <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1rethrow__error__handler.html" title="Struct rethrow_error_handler">rethrow_error_handler</a></code>:
            Does nothing but re-throw any exception that it is asked to handle. Its
            <code class="computeroutput">diagnose()</code> member functions are no-ops.
          </li>
<li class="listitem">
            <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1vs__output__error__handler.html" title="Struct vs_output_error_handler">vs_output_error_handler</a></code>:
            Directs all errors and warnings to the debugging output panel inside
            Visual Studio. Available on Windows only. Probably does nothing useful
            desirable when executed outside of Visual Studio.
          </li>
</ul></div>
<p>
        You can set the error handler to any of these, or one of your own, using
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aae7cd87f98b93f630715d9f28aff4747.html" title="Function template with_error_handler">with_error_handler()</a></code> (see <a class="link" href="tutorial.html#boost_parser.tutorial.the__parse____api" title="The parse() API">The
        <code class="computeroutput"><span class="identifier">parse</span><span class="special">()</span></code>
        API</a>). If you do not set one, <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1default__error__handler.html" title="Struct default_error_handler">default_error_handler</a></code> will
        be used.
      </p>
<h5>
<a name="boost_parser.tutorial.error_handling_and_debugging.h1"></a>
        <span class="phrase"><a name="boost_parser.tutorial.error_handling_and_debugging.how_diagnostics_are_generated"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.error_handling_and_debugging.how_diagnostics_are_generated">How
        diagnostics are generated</a>
      </h5>
<p>
        Boost.Parser only generates error messages like the ones in this page at
        failed expectation points, like <code class="computeroutput">a &gt; b</code>, where you have successfully
        parsed <code class="computeroutput">a</code>, but then cannot successfully parse <code class="computeroutput">b</code>.
        This may seem limited to you. It's actually the best that we can do.
      </p>
<p>
        In order for error handling to happen other than at expectation points, we
        have to know that there is no further processing that might take place. This
        is true because Boost.Parser has <code class="computeroutput">P1 | P2 | ... | Pn</code> parsers
        ("<code class="computeroutput">or_parser</code>s"). If any one of these parsers <code class="computeroutput">Pi</code>
        fails to match, it is not allowed to fail the parse — the next one
        (<code class="computeroutput">Pi+1</code>) might match. If we get to the end of the alternatives
        of the or_parser and <code class="computeroutput">Pn</code> fails, we still cannot fail the top-level
        parse, because the <code class="computeroutput">or_parser</code> might be a subparser within a parent
        <code class="computeroutput">or_parser</code>.
      </p>
<p>
        Ok, so what might we do? Perhaps we could at least indicate when we ran into
        end-of-input. But we cannot, for exactly the same reason already stated.
        For any parser <code class="computeroutput">P</code>, reaching end-of-input is a failure for <code class="computeroutput">P</code>,
        but not necessarily for the whole parse.
      </p>
<p>
        Perhaps we could record the farthest point ever reached during the parse,
        and report that at the top level, if the top level parser fails. That would
        be little help without knowing which parser was active when we reached that
        point. This would require some sort of repeated memory allocation, since
        in Boost.Parser the progress point of the parser is stored exclusively on
        the stack — by the time we fail the top-level parse, all those far-reaching
        stack frames are long gone. Not the best.
      </p>
<p>
        Worse still, knowing how far you got in the parse and which parser was active
        is not very useful. Consider this.
      </p>
<pre class="programlisting">namespace bp = boost::parser;
auto a_b = bp::char_('a') &gt;&gt; bp::char_('b');
auto c_b = bp::char_('c') &gt;&gt; bp::char_('b');
auto result = bp::parse("acb", a_b | c_b);
</pre>
<p>
        If we reported the farthest-reaching parser and it's position, it would be
        the <code class="computeroutput">a_b</code> parser, at position <code class="computeroutput">"bc"</code> in the
        input. Is this really enlightening? Was the error in the input putting the
        <code class="computeroutput">'a'</code> at the beginning or putting the <code class="computeroutput">'c'</code> in the
        middle? If you point the user at <code class="computeroutput">a_b</code> as the parser that failed,
        and never mention <code class="computeroutput">c_b</code>, you are potentially just steering them
        in the wrong direction.
      </p>
<p>
        All error messages must come from failed expectation points. Consider parsing
        JSON. If you open a list with <code class="computeroutput">'['</code>, you know that you're parsing
        a list, and if the list is ill-formed, you'll get an error message saying
        so. If you open an object with <code class="computeroutput">'{'</code>, the same thing is possible
        — when missing the matching <code class="computeroutput">'}'</code>, you can tell the user,
        "That's not an object", and this is useful feedback. The same thing
        with a partially parsed number, etc. If the JSON parser does not build in
        expectations like matched braces and brackets, how can Boost.Parser know
        that a missing <code class="computeroutput">'}'</code> is really a problem, and that no later parser
        will match the input even without the <code class="computeroutput">'}'</code>?
      </p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          The bottom line is that you should build expectation points into your parsers
          using <code class="computeroutput">operator&gt;</code> as much as possible.
        </p></td></tr>
</table></div>
<h5>
<a name="boost_parser.tutorial.error_handling_and_debugging.h2"></a>
        <span class="phrase"><a name="boost_parser.tutorial.error_handling_and_debugging.using_error_handlers_in_semantic_actions"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.error_handling_and_debugging.using_error_handlers_in_semantic_actions">Using
        error handlers in semantic actions</a>
      </h5>
<p>
        You can get access to the error handler within any semantic action by calling
        <code class="computeroutput">_error_handler(ctx)</code> (see <a class="link" href="tutorial.html#boost_parser.tutorial.the_parse_context" title="The Parse Context">The
        Parse Context</a>). Any error handler must have the following member functions:
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">diagnose</span><span class="special">(</span>
    <span class="identifier">diagnostic_kind</span> <span class="identifier">kind</span><span class="special">,</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span> <span class="identifier">message</span><span class="special">,</span>
    <span class="identifier">Context</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">context</span><span class="special">,</span>
    <span class="identifier">Iter</span> <span class="identifier">it</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">diagnose</span><span class="special">(</span>
    <span class="identifier">diagnostic_kind</span> <span class="identifier">kind</span><span class="special">,</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span> <span class="identifier">message</span><span class="special">,</span>
    <span class="identifier">Context</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">context</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
      </p>
<p>
        If you call the second one, the one without the iterator parameter, it will
        call the first with <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aeab1988a8b997f9eb81e5c910af70fe4.html" title="Function template _where">_where</a>(context).begin()</code>
        as the iterator parameter. The one without the iterator is the one you will
        use most often. The one with the explicit iterator parameter can be useful
        in situations where you have messages that are related to each other, associated
        with multiple locations. For instance, if you are parsing XML, you may want
        to report that a close-tag does not match its associated open-tag by showing
        the line where the open-tag was found. That may of course not be located
        anywhere near <code class="computeroutput">_where(ctx).begin()</code>. (A description of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aedbd47dbeefeba9d1e3f8ed71f41aefc.html" title="Function template _globals">_globals()</a></code> is below.)
      </p>
<pre class="programlisting">[](auto &amp; ctx) {
    // Assume we have a std::vector of open tags, and another
    // std::vector of iterators to where the open tags were parsed, in our
    // globals.
    if (_attr(ctx) != _globals(ctx).open_tags.back()) {
        std::string open_tag_msg =
            "Previous open-tag \"" + _globals(ctx).open_tags.back() + "\" here:";
        _error_handler(ctx).diagnose(
            boost::parser::diagnostic_kind::error,
            open_tag_msg,
            ctx,
            _globals(ctx).open_tags_position.back());
        std::string close_tag_msg =
            "does not match close-tag \"" + _attr(ctx) + "\" here:";
        _error_handler(ctx).diagnose(
            boost::parser::diagnostic_kind::error,
            close_tag_msg,
            ctx);

        // Explicitly fail the parse.  Diagnostics do not affect parse success.
        _pass(ctx) = false;
    }
}
</pre>
<h5>
<a name="boost_parser.tutorial.error_handling_and_debugging.h3"></a>
        <span class="phrase"><a name="boost_parser.tutorial.error_handling_and_debugging._functionname_alt__boost__parser___report_error___code__phrase_role__identifier___report_error__phrase__phrase_role__special______phrase___code___functionname__and__functionname_alt__boost__parser___report_warning___code__phrase_role__identifier___report_warning__phrase__phrase_role__special______phrase___code___functionname_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.error_handling_and_debugging._functionname_alt__boost__parser___report_error___code__phrase_role__identifier___report_error__phrase__phrase_role__special______phrase___code___functionname__and__functionname_alt__boost__parser___report_warning___code__phrase_role__identifier___report_warning__phrase__phrase_role__special______phrase___code___functionname_">_report_error() and _report_warning()</a>
      </h5>
<p>
        There are also some convenience functions that make the above code a little
        less verbose, <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aa5a0a0d4f95dedb151419d0d65bd7181.html" title="Function template _report_error">_report_error()</a></code>
        and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a77c4f2123fe4bcbde41093dd37ef3a27.html" title="Function template _report_warning">_report_warning()</a></code>:
      </p>
<pre class="programlisting">[](auto &amp; ctx) {
    // Assume we have a std::vector of open tags, and another
    // std::vector of iterators to where the open tags were parsed, in our
    // globals.
    if (_attr(ctx) != _globals(ctx).open_tags.back()) {
        std::string open_tag_msg =
            "Previous open-tag \"" + _globals(ctx).open_tags.back() + "\" here:";
        _report_error(ctx, open_tag_msg, _globals(ctx).open_tag_positions.back());
        std::string close_tag_msg =
            "does not match close-tag \"" + _attr(ctx) + "\" here:";
        _report_error(ctx, close_tag_msg);

        // Explicitly fail the parse.  Diagnostics do not affect parse success.
        _pass(ctx) = false;
    }
}
</pre>
<p>
        You should use these less verbose functions almost all the time. The only
        time you would want to use <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a9c8ae49775523bb75e651c7b4eddcc99.html" title="Function template _error_handler">_error_handler()</a></code>
        directly is when you are using a custom error handler, and you want access
        to some part of its interface besides <code class="computeroutput">diagnose()</code>.
      </p>
<p>
        Though there is support for reporting warnings using the functions above,
        none of the error handlers supplied by Boost.Parser will ever report a warning.
        Warnings are strictly for user code.
      </p>
<p>
        For more information on the rest of the error handling and diagnostic API,
        see the header reference pages for <code class="computeroutput"><a class="link" href="../headers.html#doxygen.headers.error__handling__fwd_8hpp" title="Header &lt;boost/parser/error_handling_fwd.hpp&gt;">error_handling_fwd.hpp</a></code>
        and <code class="computeroutput"><a class="link" href="../headers.html#doxygen.headers.error__handling_8hpp" title="Header &lt;boost/parser/error_handling.hpp&gt;">error_handling.hpp</a></code>.
      </p>
<h5>
<a name="boost_parser.tutorial.error_handling_and_debugging.h4"></a>
        <span class="phrase"><a name="boost_parser.tutorial.error_handling_and_debugging.creating_your_own_error_handler"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.error_handling_and_debugging.creating_your_own_error_handler">Creating
        your own error handler</a>
      </h5>
<p>
        Creating your own error handler is pretty easy; you just need to implement
        three member functions. Say you want an error handler that writes diagnostics
        to a file. Here's how you might do that.
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">logging_error_handler</span>
<span class="special">{</span>
    <span class="identifier">logging_error_handler</span><span class="special">()</span> <span class="special">{}</span>
    <span class="identifier">logging_error_handler</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span> <span class="identifier">filename</span><span class="special">)</span> <span class="special">:</span>
        <span class="identifier">filename_</span><span class="special">(</span><span class="identifier">filename</span><span class="special">),</span> <span class="identifier">ofs_</span><span class="special">(</span><span class="identifier">filename_</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ofs_</span><span class="special">)</span>
            <span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">(</span><span class="string">"Could not open file."</span><span class="special">);</span>
    <span class="special">}</span>

    <span class="comment">// This is the function called by Boost.Parser after a parser fails the</span>
    <span class="comment">// parse at an expectation point and throws a parse_error.  It is expected</span>
    <span class="comment">// to create a diagnostic message, and put it where it needs to go.  In</span>
    <span class="comment">// this case, we're writing it to a log file.  This function returns a</span>
    <span class="comment">// bp::error_handler_result, which is an enum with two enumerators -- fail</span>
    <span class="comment">// and rethrow.  Returning fail fails the top-level parse; returning</span>
    <span class="comment">// rethrow just re-throws the parse_error exception that got us here in</span>
    <span class="comment">// the first place.</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Sentinel</span><span class="special">&gt;</span>
    <span class="identifier">bp</span><span class="special">::</span><span class="identifier">error_handler_result</span>
    <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Iter</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">Sentinel</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse_error</span><span class="special">&lt;</span><span class="identifier">Iter</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">const</span>
    <span class="special">{</span>
        <span class="identifier">bp</span><span class="special">::</span><span class="identifier">write_formatted_expectation_failure_error_message</span><span class="special">(</span>
            <span class="identifier">ofs_</span><span class="special">,</span> <span class="identifier">filename_</span><span class="special">,</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">e</span><span class="special">);</span>
        <span class="keyword">return</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">error_handler_result</span><span class="special">::</span><span class="identifier">fail</span><span class="special">;</span>
    <span class="special">}</span>

    <span class="comment">// This function is for users to call within a semantic action to produce</span>
    <span class="comment">// a diagnostic.</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">&gt;</span>
    <span class="keyword">void</span> <span class="identifier">diagnose</span><span class="special">(</span>
        <span class="identifier">bp</span><span class="special">::</span><span class="identifier">diagnostic_kind</span> <span class="identifier">kind</span><span class="special">,</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span> <span class="identifier">message</span><span class="special">,</span>
        <span class="identifier">Context</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">context</span><span class="special">,</span>
        <span class="identifier">Iter</span> <span class="identifier">it</span><span class="special">)</span> <span class="keyword">const</span>
    <span class="special">{</span>
        <span class="identifier">bp</span><span class="special">::</span><span class="identifier">write_formatted_message</span><span class="special">(</span>
            <span class="identifier">ofs_</span><span class="special">,</span>
            <span class="identifier">filename_</span><span class="special">,</span>
            <span class="identifier">bp</span><span class="special">::</span><span class="identifier">_begin</span><span class="special">(</span><span class="identifier">context</span><span class="special">),</span>
            <span class="identifier">it</span><span class="special">,</span>
            <span class="identifier">bp</span><span class="special">::</span><span class="identifier">_end</span><span class="special">(</span><span class="identifier">context</span><span class="special">),</span>
            <span class="identifier">message</span><span class="special">);</span>
    <span class="special">}</span>

    <span class="comment">// This is just like the other overload of diagnose(), except that it</span>
    <span class="comment">// determines the Iter parameter for the other overload by calling</span>
    <span class="comment">// _where(ctx).</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">&gt;</span>
    <span class="keyword">void</span> <span class="identifier">diagnose</span><span class="special">(</span>
        <span class="identifier">bp</span><span class="special">::</span><span class="identifier">diagnostic_kind</span> <span class="identifier">kind</span><span class="special">,</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">string_view</span> <span class="identifier">message</span><span class="special">,</span>
        <span class="identifier">Context</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">context</span><span class="special">)</span> <span class="keyword">const</span>
    <span class="special">{</span>
        <span class="identifier">diagnose</span><span class="special">(</span><span class="identifier">kind</span><span class="special">,</span> <span class="identifier">message</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">_where</span><span class="special">(</span><span class="identifier">context</span><span class="special">).</span><span class="identifier">begin</span><span class="special">());</span>
    <span class="special">}</span>

    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">filename_</span><span class="special">;</span>
    <span class="keyword">mutable</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ofstream</span> <span class="identifier">ofs_</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
      </p>
<p>
        That's it. You just need to do the important work of the error handler in
        its call operator, and then implement the two overloads of <code class="computeroutput">diagnose()</code>
        that it must provide for use inside semantic actions. The default implementation
        of these is even available as the free function <code class="computeroutput">write_formatted_message()</code>,
        so you can just call that, as you see above. Here's how you might use it.
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Enter a list of integers, separated by commas. "</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">input</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">,</span> <span class="identifier">input</span><span class="special">);</span>

    <span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">parser</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span> <span class="special">&gt;&gt;</span> <span class="special">*(</span><span class="char">','</span> <span class="special">&gt;</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">int_</span><span class="special">);</span>
    <span class="identifier">logging_error_handler</span> <span class="identifier">error_handler</span><span class="special">(</span><span class="string">"parse.log"</span><span class="special">);</span>
    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">,</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">with_error_handler</span><span class="special">(</span><span class="identifier">parser</span><span class="special">,</span> <span class="identifier">error_handler</span><span class="special">));</span>

    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span> <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"It looks like you entered:\n"</span><span class="special">;</span>
        <span class="keyword">for</span> <span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span> <span class="special">:</span> <span class="special">*</span><span class="identifier">result</span><span class="special">)</span> <span class="special">{</span>
            <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">x</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
        <span class="special">}</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        We just define a <code class="computeroutput">logging_error_handler</code>, and pass it by reference
        to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aae7cd87f98b93f630715d9f28aff4747.html" title="Function template with_error_handler">with_error_handler()</a></code>, which decorates the top-level
        parser with the error handler. We <span class="bold"><strong>could not</strong></span>
        have written <code class="computeroutput">bp::with_error_handler(parser, logging_error_handler("parse.log"))</code>,
        because <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aae7cd87f98b93f630715d9f28aff4747.html" title="Function template with_error_handler">with_error_handler()</a></code>
        does not accept rvalues. This is becuse the error handler eventually goes
        into the parse context. The parse context only stores pointers and iterators,
        keeping it cheap to copy.
      </p>
<p>
        If we run the example and give it the input <code class="computeroutput">"1,"</code>,
        this shows up in the log file:
      </p>
<pre class="programlisting">parse.log:1:2: error: Expected int_ here (end of input):
1,
  ^
</pre>
<h5>
<a name="boost_parser.tutorial.error_handling_and_debugging.h5"></a>
        <span class="phrase"><a name="boost_parser.tutorial.error_handling_and_debugging.fixing_ill_formed_code"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.error_handling_and_debugging.fixing_ill_formed_code">Fixing
        ill-formed code</a>
      </h5>
<p>
        Sometimes, during the writing of a parser, you make a simple mistake that
        is diagnosed horrifyingly, due to the high number of template instantiations
        between the line you just wrote and the point of use (usually, the call to
        <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>). By "sometimes",
        I mean "almost always and many, many times". Boost.Parser has a
        workaround for situations like this. The workaround is to make the ill-formed
        code well-formed in as many circumstances as possible, and then do a runtime
        assert instead.
      </p>
<p>
        Usually, C++ programmers try whenever they can to catch mistakes as early
        as they can. That usually means making as much bad code ill-formed as possible.
        Counter-intuitively, this does not work well in parser combinator situations.
        For an example of just how dramatically different these two debugging scenarios
        can be with Boost.Parser, please see the very long discussion in the <a class="link" href="rationale.html#boost_parser.rationale._classname_alt__boost__parser__none___code__phrase_role__identifier__none__phrase___code___classname__is_weird"><code class="computeroutput"><span class="identifier">none</span></code> is weird</a> section of <a class="link" href="rationale.html" title="Rationale">Rationale</a>.
      </p>
<p>
        If you are morally opposed to this approach, or just hate fun, good news:
        you can turn off the use of this technique entirely by defining <code class="computeroutput">BOOST_PARSER_NO_RUNTIME_ASSERTIONS</code>.
      </p>
<h5>
<a name="boost_parser.tutorial.error_handling_and_debugging.h6"></a>
        <span class="phrase"><a name="boost_parser.tutorial.error_handling_and_debugging.runtime_debugging"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.error_handling_and_debugging.runtime_debugging">Runtime
        debugging</a>
      </h5>
<p>
        Debugging parsers is hard. Any parser above a certain complexity level is
        nearly impossible to debug simply by looking at the parser's code. Stepping
        through the parse in a debugger is even worse. To provide a reasonable chance
        of debugging your parsers, Boost.Parser has a trace mode that you can turn
        on simply by providing an extra parameter to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        or <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab9e8e193ef875ca869f2d6d43fa61fc5.html" title="Function template callback_parse">callback_parse()</a></code>:
      </p>
<pre class="programlisting">boost::parser::parse(input, parser, boost::parser::trace::on);
</pre>
<p>
        Every overload of <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
        and <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab9e8e193ef875ca869f2d6d43fa61fc5.html" title="Function template callback_parse">callback_parse()</a></code> takes this final parameter,
        which is defaulted to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a70159b38d52d5203b78c0078c2f4e7f6.html" title="Type trace">boost::parser::trace</a>::off</code>.
      </p>
<p>
        If we trace a substantial parser, we will see a <span class="bold"><strong>lot</strong></span>
        of output. Each code point of the input must be considered, one at a time,
        to see if a certain rule matches. An an example, let's trace a parse using
        the JSON parser from <a class="link" href="extended_examples.html#boost_parser.extended_examples.parsing_json" title="Parsing JSON">Parsing
        JSON</a>. The input is <code class="computeroutput">"null"</code>. <code class="computeroutput">null</code>
        is one of the types that a Javascript value can have; the top-level parser
        in the JSON parser example is:
      </p>
<pre class="programlisting">auto const value_p_def =
    number | bp::bool_ | null | string | array_p | object_p;
</pre>
<p>
        So, a JSON value can be a number, or a Boolean, a <code class="computeroutput">null</code>, etc.
        During the parse, each alternative will be tried in turn, until one is matched.
        I picked <code class="computeroutput">null</code> because it is relatively close to the beginning
        of the <code class="computeroutput">value_p_def</code> alternative parser. Even so, the output is
        pretty huge. Let's break it down as we go:
      </p>
<p>
</p>
<pre class="programlisting">[begin value; input="null"]
</pre>
<p>
      </p>
<p>
        Each parser is traced as <code class="computeroutput">[begin foo; ...]</code>, then the parsing
        operations themselves, and then <code class="computeroutput">[end foo; ...]</code>. The name of
        a rule is used as its name in the <code class="computeroutput">begin</code> and <code class="computeroutput">end</code>
        parts of the trace. Non-rules have a name that is similar to the way the
        parser looked when you wrote it. Most lines will have the next few code points
        of the input quoted, as we have here (<code class="computeroutput">input="null"</code>).
      </p>
<p>
</p>
<pre class="programlisting">[begin number | bool_ | null | string | ...; input="null"]
</pre>
<p>
      </p>
<p>
        This shows the beginning of the parser <span class="bold"><strong>inside</strong></span>
        the rule <code class="computeroutput">value</code> — the parser that actually does all the
        work. In the example code, this parser is called <code class="computeroutput">value_p_def</code>.
        Since it isn't a rule, we have no name for it, so we show its implementation
        in terms of subparsers. Since it is a bit long, we don't print the entire
        thing. That's why that ellipsis is there.
      </p>
<p>
</p>
<pre class="programlisting">[begin number; input="null"]
  [begin raw[lexeme[ &gt;&gt; ...]][&lt;&lt;action&gt;&gt;]; input="null"]
</pre>
<p>
      </p>
<p>
        Now we're starting to see the real work being done. <code class="computeroutput">number</code> is
        a somewhat complicated parser that does not match <code class="computeroutput">"null"</code>,
        so there's a lot to wade through when following the trace of its attempt
        to do so. One thing to note is that, since we cannot print a name for an
        action, we just print <code class="computeroutput">"&lt;&lt;action&gt;&gt;"</code>. Something
        similar happens when we come to an attribute that we cannot print, because
        it has no stream insertion operation. In that case, <code class="computeroutput">"&lt;&lt;unprintable-value&gt;&gt;"</code>
        is printed.
      </p>
<p>
</p>
<pre class="programlisting">    [begin raw[lexeme[ &gt;&gt; ...]]; input="null"]
      [begin lexeme[-char_('-') &gt;&gt; char_('1', '9') &gt;&gt; ... | ... &gt;&gt; ...]; input="null"]
        [begin -char_('-') &gt;&gt; char_('1', '9') &gt;&gt; *digit | char_('0') &gt;&gt; -(char_('.') &gt;&gt; ...) &gt;&gt; -( &gt;&gt; ...); input="null"]
          [begin -char_('-'); input="null"]
            [begin char_('-'); input="null"]
              no match
            [end char_('-'); input="null"]
            matched ""
            attribute: &lt;&lt;empty&gt;&gt;
          [end -char_('-'); input="null"]
          [begin char_('1', '9') &gt;&gt; *digit | char_('0'); input="null"]
            [begin char_('1', '9') &gt;&gt; *digit; input="null"]
              [begin char_('1', '9'); input="null"]
                no match
              [end char_('1', '9'); input="null"]
              no match
            [end char_('1', '9') &gt;&gt; *digit; input="null"]
            [begin char_('0'); input="null"]
              no match
            [end char_('0'); input="null"]
            no match
          [end char_('1', '9') &gt;&gt; *digit | char_('0'); input="null"]
          no match
        [end -char_('-') &gt;&gt; char_('1', '9') &gt;&gt; *digit | char_('0') &gt;&gt; -(char_('.') &gt;&gt; ...) &gt;&gt; -( &gt;&gt; ...); input="null"]
        no match
      [end lexeme[-char_('-') &gt;&gt; char_('1', '9') &gt;&gt; ... | ... &gt;&gt; ...]; input="null"]
      no match
    [end raw[lexeme[ &gt;&gt; ...]]; input="null"]
    no match
  [end raw[lexeme[ &gt;&gt; ...]][&lt;&lt;action&gt;&gt;]; input="null"]
  no match
[end number; input="null"]
[begin bool_; input="null"]
  no match
[end bool_; input="null"]
</pre>
<p>
      </p>
<p>
        <code class="computeroutput">number</code> and <code class="computeroutput">boost::parser::bool_</code> did not match,
        but <code class="computeroutput">null</code> will:
      </p>
<p>
</p>
<pre class="programlisting">[begin null; input="null"]
  [begin "null" &gt;&gt; attr(null); input="null"]
    [begin "null"; input="null"]
      [begin string("null"); input="null"]
        matched "null"
        attribute:
      [end string("null"); input=""]
      matched "null"
      attribute: null
</pre>
<p>
      </p>
<p>
        Finally, this parser actually matched, and the match generated the attribute
        <code class="computeroutput">null</code>, which is a special value of the type <code class="computeroutput">json::value</code>.
        Since we were matching a string literal <code class="computeroutput">"null"</code>, earlier
        there was no attribute until we reached the <code class="computeroutput">attr(null)</code> parser.
      </p>
<p>
</p>
<pre class="programlisting">        [end "null"; input=""]
        [begin attr(null); input=""]
          matched ""
          attribute: null
        [end attr(null); input=""]
        matched "null"
        attribute: null
      [end "null" &gt;&gt; attr(null); input=""]
      matched "null"
      attribute: null
    [end null; input=""]
    matched "null"
    attribute: null
  [end number | bool_ | null | string | ...; input=""]
  matched "null"
  attribute: null
[end value; input=""]
--------------------
parse succeeded
--------------------
</pre>
<p>
      </p>
<p>
        At the very end of the parse, the trace code prints out whether the top-level
        parse succeeded or failed.
      </p>
<p>
        Some things to be aware of when looking at Boost.Parser trace output:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            There are some parsers you don't know about, because they are not directly
            documented. For instance, <code class="computeroutput">p[a]</code> forms an <code class="computeroutput">action_parser</code>
            containing the parser <code class="computeroutput">p</code> and semantic action <code class="computeroutput">a</code>.
            This is essentially an implementation detail, but unfortunately the trace
            output does not hide this from you.
          </li>
<li class="listitem">
            For a parser <code class="computeroutput">p</code>, the trace-name may be intentionally different
            from the actual structure of <code class="computeroutput">p</code>. For example, in the trace
            above, you see a parser called simply <code class="computeroutput">"null"</code>.
            This parser is actually <code class="computeroutput">boost::parser::omit[boost::parser::string("null")]</code>,
            but what you typically write is just <code class="computeroutput">"null"</code>, so
            that's the name used. There are two special cases like this: the one
            described here for <code class="computeroutput">omit[string]</code>, and another for <code class="computeroutput">omit[char_]</code>.
          </li>
<li class="listitem">
            Since there are no other special cases for how parser names are printed,
            you may see parsers that are unlike what you wrote in your code. In the
            sections about the parsers and combining operations, you will sometimes
            see a parser or combining operation described in terms of an equivalent
            parser. For example, <code class="computeroutput">if_(pred)[p]</code> is described as "Equivalent
            to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a>(pred)
            &gt;&gt; p</code>". In a trace, you will not see <code class="computeroutput">if_</code>;
            you will see <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ae99af5798fd88c0cfd424c181dc13d09.html" title="Global eps">eps</a></code>
            and <code class="computeroutput">p</code> instead.
          </li>
<li class="listitem">
            The values of arguments passed to parsers is printed whenever possible.
            Sometimes, a parse argument is not a value itself, but a callable that
            produces that value. In these cases, you'll see the resolved value of
            the parse argument.
          </li>
</ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.memory_allocation"></a><a class="link" href="tutorial.html#boost_parser.tutorial.memory_allocation" title="Memory Allocation">Memory Allocation</a>
</h3></div></div></div>
<p>
        Boost.Parser seldom allocates memory. The exceptions to this are:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code>
            allocates memory for the symbol/attribute pairs it contains. If symbols
            are added during the parse, allocations must also occur then. The data
            structure used by <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code> is also a trie,
            which is a node-based tree. So, lots of allocations are likely if you
            use <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code>.
          </li>
<li class="listitem">
            The error handlers that can take a file name allocate memory for the
            file name, if one is provided.
          </li>
<li class="listitem">
            If trace is turned on by passing <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a70159b38d52d5203b78c0078c2f4e7f6.html" title="Type trace">boost::parser::trace</a>::on</code> to a top-level
            parsing function, the names of parsers are allocated.
          </li>
<li class="listitem">
            When a failed expectation is encountered (using <code class="computeroutput">operator&gt;</code>),
            the name of the failed parser is placed into a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>,
            which will usually cause an allocation.
          </li>
<li class="listitem">
            <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a7e079d756d52cf5fc94cbdca53bb8b4f.html" title="Function template string">string()</a></code>'s attribute is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>, the use of which implies allocation.
            You can avoid this allocation by explicitly using a different string
            type for the attribute that does not allocate.
          </li>
<li class="listitem">
            The attribute for <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ad95e37e5cf4468149eec5f774ad977f3.html" title="Function template repeat">repeat</a>(p)</code> in
            all its forms, including <code class="computeroutput">operator*</code>, <code class="computeroutput">operator+</code>,
            and <code class="computeroutput">operator%</code>, is <code class="computeroutput">std::vector&lt;<span class="emphasis"><em><code class="literal">ATTR</code></em></span>(p)&gt;</code>,
            the use of which implies allocation. You can avoid this allocation by
            explicitly using a different sequence container for the attribute that
            does not allocate. <code class="computeroutput">boost::container::static_vector</code> or C++26's
            <code class="computeroutput">std::inplace_vector</code> may be useful as such replacements.
          </li>
</ul></div>
<p>
        With the exception of allocating the name of the parser that was expected
        in a failed expectation situation, Boost.Parser does not does not allocate
        unless you tell it to, by using <code class="computeroutput"><a class="link" href="../doxygen/headers/structboost_1_1parser_1_1symbols.html" title="Struct template symbols">symbols</a></code>, using a particular
        error_handler, turning on trace, or parsing into attributes that allocate.
      </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.best_practices"></a><a class="link" href="tutorial.html#boost_parser.tutorial.best_practices" title="Best Practices">Best Practices</a>
</h3></div></div></div>
<h5>
<a name="boost_parser.tutorial.best_practices.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.best_practices.parse_unicode_from_the_start"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.best_practices.parse_unicode_from_the_start">Parse
        unicode from the start</a>
      </h5>
<p>
        If you want to parse ASCII, using the Unicode parsing API will not actually
        cost you anything. Your input will be parsed, <code class="computeroutput">char</code> by <code class="computeroutput">char</code>,
        and compared to values that are Unicode code points (which are <code class="computeroutput">char32_t</code>s).
        One caveat is that there may be an extra branch on each char, if the input
        is UTF-8. If your performance requirements can tolerate this, your life will
        be much easier if you just start with Unicode and stick with it.
      </p>
<p>
        Starting with Unicode support and UTF-8 input will allow you to properly
        handle unexpected input, like non-ASCII languages (that's most of them),
        with no additional effort on your part.
      </p>
<h5>
<a name="boost_parser.tutorial.best_practices.h1"></a>
        <span class="phrase"><a name="boost_parser.tutorial.best_practices.write_rules__and_test_them_in_isolation"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.best_practices.write_rules__and_test_them_in_isolation">Write
        rules, and test them in isolation</a>
      </h5>
<p>
        Treat rules as the unit of work in your parser. Write a rule, test its corners,
        and then use it to build larger rules or parsers. This allows you to get
        better coverage with less work, since exercising all the code paths of your
        rules, one by one, keeps the combinatorial number of paths through your code
        manageable.
      </p>
<h5>
<a name="boost_parser.tutorial.best_practices.h2"></a>
        <span class="phrase"><a name="boost_parser.tutorial.best_practices.prefer_auto_generated_attributes_to_semantic_actions"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.best_practices.prefer_auto_generated_attributes_to_semantic_actions">Prefer
        auto-generated attributes to semantic actions</a>
      </h5>
<p>
        There are multiple ways to get attributes out of a parser. You can:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            use whatever attribute the parser generates;
          </li>
<li class="listitem">
            provide an attribute out-argument to <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1ab68519dff2a5635d6a11296874fc154d.html" title="Function template parse">parse()</a></code>
            for the parser to fill in;
          </li>
<li class="listitem">
            use one or more semantic actions to assign attributes from the parser
            to variables outside the parser;
          </li>
<li class="listitem">
            use callback parsing to provide attributes via callback calls.
          </li>
</ul></div>
<p>
        All of these are fairly similar in how much effort they require, except for
        the semantic action method. For the semantic action approach, you need to
        have values to fill in from your parser, and keep them in scope for the duration
        of the parse.
      </p>
<p>
        It is much more straight forward, and leads to more reusable parsers, to
        have the parsers produce the attributes of the parse directly as a result
        of the parse.
      </p>
<p>
        This does not mean that you should never use semantic actions. They are sometimes
        necessary. However, you should default to using the other non-semantic action
        methods, and only use semantic actions with a good reason.
      </p>
<h5>
<a name="boost_parser.tutorial.best_practices.h3"></a>
        <span class="phrase"><a name="boost_parser.tutorial.best_practices.if_your_parser_takes_end_user_input__give_rules_names_that_you_would_want_an_end_user_to_see"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.best_practices.if_your_parser_takes_end_user_input__give_rules_names_that_you_would_want_an_end_user_to_see">If
        your parser takes end-user input, give rules names that you would want an
        end-user to see</a>
      </h5>
<p>
        A typical error message produced by Boost.Parser will say something like,
        "Expected FOO here", where FOO is some rule or parser. Give your
        rules names that will read well in error messages like this. For instance,
        the JSON examples have these rules:
      </p>
<pre class="programlisting">bp::rule&lt;class escape_seq, uint32_t&gt; const escape_seq =
    "\\uXXXX hexadecimal escape sequence";
bp::rule&lt;class escape_double_seq, uint32_t, double_escape_locals&gt; const
    escape_double_seq = "\\uXXXX hexadecimal escape sequence";
bp::rule&lt;class single_escaped_char, uint32_t&gt; const single_escaped_char =
    "'\"', '\\', '/', 'b', 'f', 'n', 'r', or 't'";
</pre>
<p>
        Some things to note:
      </p>
<p>
        - <code class="computeroutput">escape_seq</code> and <code class="computeroutput">escape_double_seq</code> have the same
        name-string. To an end-user who is trying to figure out why their input failed
        to parse, it doesn't matter which kind of result a parser rule generates.
        They just want to know how to fix their input. For either rule, the fix is
        the same: put a hexadecimal escape sequence there.
      </p>
<p>
        - <code class="computeroutput">single_escaped_char</code> has a terrible-looking name. However,
        it's not really used as a name anywhere per se. In error messages, it works
        nicely, though. The error will be "Expected '"', '', '/', 'b',
        'f', 'n', 'r', or 't' here", which is pretty helpful.
      </p>
<h5>
<a name="boost_parser.tutorial.best_practices.h4"></a>
        <span class="phrase"><a name="boost_parser.tutorial.best_practices.have_a_simple_test_that_you_can_run_to_find_ill_formed_code_as_asserts"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.best_practices.have_a_simple_test_that_you_can_run_to_find_ill_formed_code_as_asserts">Have
        a simple test that you can run to find ill-formed-code-as-asserts</a>
      </h5>
<p>
        Most of these errors are found at parser construction time, so no actual
        parsing is even necessary. For instance, a test case might look like this:
      </p>
<pre class="programlisting">TEST(my_parser_tests, my_rule_test) {
    my_rule r;
}
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_parser.tutorial.writing_your_own_parsers"></a><a class="link" href="tutorial.html#boost_parser.tutorial.writing_your_own_parsers" title="Writing Your Own Parsers">Writing
      Your Own Parsers</a>
</h3></div></div></div>
<p>
        You should probably never need to write your own low-level parser. You have
        primitives like <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a289f0b7681e314892648e2768a040d56.html" title="Global char_">char_</a></code>
        from which to build up the parsers that you need. It is unlikely that you're
        going to need to do things on a lower level than a single character.
      </p>
<p>
        However. Some people are obsessed with writing everything for themselves.
        We call them C++ programmers. This section is for them. However, this section
        is not an in-depth tutorial. It is a basic orientation to get you familiar
        enough with all the moving parts of writing a parser that you can then learn
        by reading the Boost.Parser code.
      </p>
<p>
        Each parser must provide two overloads of a function <code class="computeroutput">call()</code>.
        One overload parses, producing an attribute (which may be the special no-attribute
        type <code class="computeroutput">detail::nope</code>). The other one parses, filling in a given
        attribute. The type of the given attribute is a template parameter, so it
        can take any type that you can form a reference to.
      </p>
<p>
        Let's take a look at a Boost.Parser parser, <code class="computeroutput">opt_parser</code>. This
        is the parser produced by use of <code class="computeroutput">operator-</code>. First, here is the
        beginning of its definition.
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Parser</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">opt_parser</span>
<span class="special">{</span>
</pre>
<p>
      </p>
<p>
        The end of its definition is:
      </p>
<p>
</p>
<pre class="programlisting">    <span class="identifier">Parser</span> <span class="identifier">parser_</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
      </p>
<p>
        As you can see, <code class="computeroutput">opt_parser</code>'s only data member is the parser
        it adapts, <code class="computeroutput">parser_</code>. Here is its attribute-generating overload
        to <code class="computeroutput">call()</code>.
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span>
    <span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">,</span>
    <span class="keyword">typename</span> <span class="identifier">Sentinel</span><span class="special">,</span>
    <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">,</span>
    <span class="keyword">typename</span> <span class="identifier">SkipParser</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">call</span><span class="special">(</span>
    <span class="identifier">Iter</span> <span class="special">&amp;</span> <span class="identifier">first</span><span class="special">,</span>
    <span class="identifier">Sentinel</span> <span class="identifier">last</span><span class="special">,</span>
    <span class="identifier">Context</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">context</span><span class="special">,</span>
    <span class="identifier">SkipParser</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">skip</span><span class="special">,</span>
    <span class="identifier">detail</span><span class="special">::</span><span class="identifier">flags</span> <span class="identifier">flags</span><span class="special">,</span>
    <span class="keyword">bool</span> <span class="special">&amp;</span> <span class="identifier">success</span><span class="special">)</span> <span class="keyword">const</span>
<span class="special">{</span>
    <span class="keyword">using</span> <span class="identifier">attr_t</span> <span class="special">=</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">parser_</span><span class="special">.</span><span class="identifier">call</span><span class="special">(</span>
        <span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">success</span><span class="special">));</span>
    <span class="identifier">detail</span><span class="special">::</span><span class="identifier">optional_of</span><span class="special">&lt;</span><span class="identifier">attr_t</span><span class="special">&gt;</span> <span class="identifier">retval</span><span class="special">;</span>
    <span class="identifier">call</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">success</span><span class="special">,</span> <span class="identifier">retval</span><span class="special">);</span>
    <span class="keyword">return</span> <span class="identifier">retval</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        First, let's look at the template and function parameters.
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            <code class="computeroutput">Iter &amp; first</code> is the iterator. It is taken as an out-param.
            It is the responsibility of <code class="computeroutput">call()</code> to advance <code class="computeroutput">first</code>
            if and only if the parse succeeds.
          </li>
<li class="listitem">
            <code class="computeroutput">Sentinel last</code> is the sentinel. If the parse has not yet
            succeeded within <code class="computeroutput">call()</code>, and <code class="computeroutput">first == last</code>
            is <code class="computeroutput">true</code>, <code class="computeroutput">call()</code> must fail (by setting <code class="computeroutput">bool
            &amp; success</code> to <code class="computeroutput">false</code>).
          </li>
<li class="listitem">
            <code class="computeroutput">Context const &amp; context</code> is the parse context. It will
            be some specialization of <code class="computeroutput">detail::parse_context</code>. The context
            is used in any call to a subparser's <code class="computeroutput">call()</code>, and in some
            cases a new context should be created, and the new context passed to
            a subparser instead; more on that below.
          </li>
<li class="listitem">
            <code class="computeroutput">SkipParser const &amp; skip</code> is the current skip parser.
            <code class="computeroutput">skip</code> should be used at the beginning of the parse, and in
            between any two uses of any subparser(s).
          </li>
<li class="listitem">
            <code class="computeroutput">detail::flags flags</code> are a collection of flags indicating
            various things about the current state of the parse. <code class="computeroutput">flags</code>
            is concerned with whether to produce attributes at all; whether to apply
            the skip parser <code class="computeroutput">skip</code>; whether to produce a verbose trace
            (as when <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a70159b38d52d5203b78c0078c2f4e7f6.html" title="Type trace">boost::parser::trace</a>::on</code>
            is passed at the top level); and whether we are currently inside the
            utility function <code class="computeroutput">detail::apply_parser</code>.
          </li>
<li class="listitem">
            <code class="computeroutput">bool &amp; success</code> is the final function parameter. It should
            be set to <code class="computeroutput">true</code> if the parse succeeds, and <code class="computeroutput">false</code>
            otherwise.
          </li>
</ul></div>
<p>
        Now the body of the function. Notice that it just dispatches to the other
        <code class="computeroutput">call()</code> overload. This is really common, since both overloads
        need to to the same parsing; only the attribute may differ. The first line
        of the body defines <code class="computeroutput">attr_t</code>, the default attribute type of our
        wrapped parser <code class="computeroutput">parser_</code>. It does this by getting the <code class="computeroutput">decltype()</code>
        of a use of <code class="computeroutput">parser_.call()</code>. (This is the logic represented by
        <span class="emphasis"><em><code class="literal">ATTR</code></em></span><code class="computeroutput"><span class="special">()</span></code>
        in the rest of the documentation.) Since <code class="computeroutput">opt_parser</code> represents
        an optional value, the natural type for its attribute is <code class="computeroutput">std::optional&lt;<span class="emphasis"><em><code class="literal">ATTR</code></em></span>(parser)&gt;</code>.
        However, this does not work for all cases. In particular, it does not work
        for the "no-attribute" type <code class="computeroutput">detail::nope</code>, nor for
        <code class="computeroutput">std::optional&lt;T&gt;</code> — <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span>(--p)</code>
        is just <code class="computeroutput"><span class="emphasis"><em><code class="literal">ATTR</code></em></span>(-p)</code>. So,
        the second line uses an alias that takes care of those details, <code class="computeroutput">detail::optional_of&lt;&gt;</code>.
        The third line just calls the other overload of <code class="computeroutput">call()</code>, passing
        <code class="computeroutput">retval</code> as the out-param. Finally, <code class="computeroutput">retval</code> is returned
        on the last line.
      </p>
<p>
        Now, on to the other overload.
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span>
    <span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">,</span>
    <span class="keyword">typename</span> <span class="identifier">Sentinel</span><span class="special">,</span>
    <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">,</span>
    <span class="keyword">typename</span> <span class="identifier">SkipParser</span><span class="special">,</span>
    <span class="keyword">typename</span> <span class="identifier">Attribute</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">call</span><span class="special">(</span>
    <span class="identifier">Iter</span> <span class="special">&amp;</span> <span class="identifier">first</span><span class="special">,</span>
    <span class="identifier">Sentinel</span> <span class="identifier">last</span><span class="special">,</span>
    <span class="identifier">Context</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">context</span><span class="special">,</span>
    <span class="identifier">SkipParser</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">skip</span><span class="special">,</span>
    <span class="identifier">detail</span><span class="special">::</span><span class="identifier">flags</span> <span class="identifier">flags</span><span class="special">,</span>
    <span class="keyword">bool</span> <span class="special">&amp;</span> <span class="identifier">success</span><span class="special">,</span>
    <span class="identifier">Attribute</span> <span class="special">&amp;</span> <span class="identifier">retval</span><span class="special">)</span> <span class="keyword">const</span>
<span class="special">{</span>
    <span class="special">[[</span><span class="identifier">maybe_unused</span><span class="special">]]</span> <span class="keyword">auto</span> <span class="identifier">_</span> <span class="special">=</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">scoped_trace</span><span class="special">(</span>
        <span class="special">*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">retval</span><span class="special">);</span>

    <span class="identifier">detail</span><span class="special">::</span><span class="identifier">skip</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">);</span>

    <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">gen_attrs</span><span class="special">(</span><span class="identifier">flags</span><span class="special">))</span> <span class="special">{</span>
        <span class="identifier">parser_</span><span class="special">.</span><span class="identifier">call</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">success</span><span class="special">);</span>
        <span class="identifier">success</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
        <span class="keyword">return</span><span class="special">;</span>
    <span class="special">}</span>

    <span class="identifier">parser_</span><span class="special">.</span><span class="identifier">call</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">success</span><span class="special">,</span> <span class="identifier">retval</span><span class="special">);</span>
    <span class="identifier">success</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        The template and function parameters here are identical to the ones from
        the other overload, except that we have <code class="computeroutput">Attribute &amp; retval</code>,
        our out-param.
      </p>
<p>
        Let's look at the implementation a bit at a time.
      </p>
<p>
</p>
<pre class="programlisting"><span class="special">[[</span><span class="identifier">maybe_unused</span><span class="special">]]</span> <span class="keyword">auto</span> <span class="identifier">_</span> <span class="special">=</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">scoped_trace</span><span class="special">(</span>
    <span class="special">*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">retval</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        This defines a RAII trace object that will produce the verbose trace requested
        by the user if they passed <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1a70159b38d52d5203b78c0078c2f4e7f6.html" title="Type trace">boost::parser::trace</a>::on</code> to the top-level
        parse. It only has effect if <code class="computeroutput">detail::enable_trace(flags)</code> is
        <code class="computeroutput">true</code>. If trace is enabled, it will show the state of the parse
        at the point at which it is defined, and then again when it goes out of scope.
      </p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
          For the tracing code to work, you must define an overload of <code class="computeroutput">detail::print_parser</code>
          for your new parser type/template. See <code class="computeroutput">&lt;boost/parser/detail/printing.hpp&gt;</code>
          for examples.
        </p></td></tr>
</table></div>
<p>
</p>
<pre class="programlisting"><span class="identifier">detail</span><span class="special">::</span><span class="identifier">skip</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        This one is pretty simple; it just applies the skip parser. <code class="computeroutput">opt_parser</code>
        only has one subparser, but if it had more than one, or if it had one that
        it applied more than once, it would need to repeat this line using <code class="computeroutput">skip</code>
        between every pair of uses of any subparser.
      </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">if</span> <span class="special">(!</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">gen_attrs</span><span class="special">(</span><span class="identifier">flags</span><span class="special">))</span> <span class="special">{</span>
    <span class="identifier">parser_</span><span class="special">.</span><span class="identifier">call</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">success</span><span class="special">);</span>
    <span class="identifier">success</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
    <span class="keyword">return</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        This path accounts for the case where we don't want to generate attributes
        at all, perhaps because this parser sits inside an <code class="computeroutput"><a class="link" href="../doxygen/headers/namespaceboost_1_1parser_1aba924d9dafe70d651680058e6004f31e.html" title="Global omit">omit[]</a></code>
        directive.
      </p>
<p>
</p>
<pre class="programlisting"><span class="identifier">parser_</span><span class="special">.</span><span class="identifier">call</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">context</span><span class="special">,</span> <span class="identifier">skip</span><span class="special">,</span> <span class="identifier">flags</span><span class="special">,</span> <span class="identifier">success</span><span class="special">,</span> <span class="identifier">retval</span><span class="special">);</span>
<span class="identifier">success</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
</pre>
<p>
      </p>
<p>
        This is the other, typical, path. Here, we do want to generate attributes,
        and so we do the same call to <code class="computeroutput">parser_.call()</code>, except that we
        also pass <code class="computeroutput">retval</code>.
      </p>
<p>
        Note that we set <code class="computeroutput">success</code> to <code class="computeroutput">true</code> after the call
        to <code class="computeroutput">parser_.call()</code> in both code paths. Since <code class="computeroutput">opt_parser</code>
        is zero-or-one, if the subparser fails, <code class="computeroutput">opt_parse</code> still succeeds.
      </p>
<h5>
<a name="boost_parser.tutorial.writing_your_own_parsers.h0"></a>
        <span class="phrase"><a name="boost_parser.tutorial.writing_your_own_parsers.when_to_make_a_new_parse_context"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.writing_your_own_parsers.when_to_make_a_new_parse_context">When
        to make a new parse context</a>
      </h5>
<p>
        Sometimes, you need to change something about the parse context before calling
        a subparser. For instance, <code class="computeroutput">rule_parser</code> sets up the value, locals,
        etc., that are available for that rule. <code class="computeroutput">action_parser</code> adds the
        generated attribute to the context (available as <code class="computeroutput">_attr(ctx)</code>).
        Contexts are immutable in Boost.Parser. To "modify" one for a subparser,
        you create a new one with the appropriate call to <code class="computeroutput">detail::make_context()</code>.
      </p>
<h5>
<a name="boost_parser.tutorial.writing_your_own_parsers.h1"></a>
        <span class="phrase"><a name="boost_parser.tutorial.writing_your_own_parsers._code_detail__apply_parser____code_"></a></span><a class="link" href="tutorial.html#boost_parser.tutorial.writing_your_own_parsers._code_detail__apply_parser____code_"><code class="computeroutput">detail::apply_parser()</code></a>
      </h5>
<p>
        Sometimes a parser needs to operate on an out-param that is not exactly the
        same as its default attribute, but that is compatible in some way. To do
        this, it's often useful for the parser to call itself, but with slightly
        different parameters. <code class="computeroutput">detail::apply_parser()</code> helps with this.
        See the out-param overload of <code class="computeroutput">repeat_parser::call()</code> for an example.
        Note that since this creates a new scope for the ersatz parser, the <code class="computeroutput">scoped_trace</code>
        object needs to know whether we're inside <code class="computeroutput">detail::apply_parser</code>
        or not.
      </p>
<p>
        That's a lot, I know. Again, this section is not meant to be an in-depth
        tutorial. You know enough now that the parsers in <code class="computeroutput">parser.hpp</code>
        are at least readable.
      </p>
</div>
</div>
<div class="copyright-footer">Copyright © 2020 T. Zachary Laine<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cheat_sheet.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../parser.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="extended_examples.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
